m5 vs m6i vs m7i: cost and price-performance compared
Hourly rates, performance per dollar, and migration paths for AWS general-purpose EC2 families. When to migrate to m7i, when to skip straight to Graviton m7g, and when older families still make sense.
Quick answer
For new general-purpose AWS workloads in 2026: pick m7i (Intel) or m7g (Graviton/ARM) if available. m7i is 15-20% better price-performance than m5 at a slightly higher hourly rate. m7g is 20% cheaper than m7i if your workload runs on ARM64. Keep m5 and m6i only if you're on existing Reserved Instances or have specific compatibility constraints.
AWS releases a new general-purpose instance family every two to three years. m5 (2018), m6i (2021), m7i (2023). Each generation gets cheaper per unit of performance, but the hourly rate doesn't drop. So picking the right family is a price-performance question, not just a price question. This post compares the three on real numbers and tells you which to pick for which workload.
The hourly rates side by side
In us-east-1, the on-demand Linux prices for the xlarge size:
- m5.xlarge: $0.192/hour ($140.16/month)
- m6i.xlarge: $0.192/hour ($140.16/month)
- m7i.xlarge: $0.2016/hour ($147.17/month)
- m7g.xlarge (Graviton): $0.1632/hour ($119.14/month)
Two things stand out. First, m5 and m6i are the same hourly rate. m6i replaced m5 at the same price with better performance, which is what you want from a generation refresh. Second, m7i is about 5% more than m6i per hour. That hourly increase is what makes some people hesitate to migrate.
For the full pricing breakdown including how C3X estimates EC2 across families, see the aws_instance catalog page.
Performance per dollar, the real metric
Hourly rates don't tell the whole story. What matters is whether the workload completes faster on the newer instance, which reduces total instance-hours billed.
AWS publishes benchmark comparisons claiming m7i has up to 15% better price-performance than m6i. Independent benchmarks from AnandTech, Phoronix, and the AWS performance team typically show:
- m6i vs m5: 15-20% better single-threaded performance
- m7i vs m6i: 12-18% better single-threaded performance
- m7i vs m5: 30-40% better single-threaded performance combined
For workloads that scale with CPU (build systems, compilers, batch processing, video encoding), m7i finishes faster. If your CI build takes 10 minutes on m5.xlarge and 7 minutes on m7i.xlarge, you pay for 70% as many minutes on m7i. Even at the slightly higher hourly rate, total cost drops.
For workloads bounded by something other than CPU (network I/O, disk I/O, waiting for external APIs), the speed advantage is much smaller. A web server that spends 95% of its time waiting on downstream services doesn't run much faster on m7i.
The migration cost
m5, m6i, and m7i are all x86-64. Migration between them is a Terraform attribute change:
resource "aws_instance" "api" {
ami = "ami-..."
instance_type = "m7i.xlarge" # was "m5.xlarge"
# everything else unchanged
}Apply, terminate the old instance, the new one starts. For stateless services behind a load balancer, this is zero-downtime with rolling deployment. For stateful workloads, you need a maintenance window or the usual blue/green pattern.
Migrating to Graviton (m7g) is more involved because the CPU architecture changes from x86-64 to ARM64. Almost all modern runtimes (Go, Python, Node, JVM, Ruby) have ARM64 builds and run natively, but you need to rebuild your container images for ARM64 or use multi-arch images. For most teams that's a one-day project; the savings then accrue forever.
When the slightly higher hourly rate doesn't pay back
Three scenarios where m7i's higher hourly rate isn't offset by performance:
Idle services
A service that runs 24/7 but is only busy 5% of the time spends most of its instance-hours waiting. The performance advantage of m7i doesn't translate to fewer instance-hours; you pay 5% more for the same continuous existence.
Better solution: use Auto Scaling to scale down idle services, or switch to Spot, or move to serverless (Lambda, Fargate) which truly scales to zero.
Workloads pinned by external systems
If your service handles fixed-rate traffic from an external system (e.g., 100 RPS from a partner integration), running on a faster CPU doesn't reduce instance-hours. The 100 RPS still streams in for 24 hours per day regardless of CPU speed.
Better solution: right-size to the actual CPU need. A smaller m7i (m7i.large instead of m7i.xlarge) handles the same fixed-rate traffic at half the cost.
Memory-bound workloads
If your workload uses 90% of an instance's memory and is memory- bound (Postgres with a 30 GB working set, Redis caches, large in-memory data structures), CPU upgrades don't help. The bottleneck is bytes, not cycles.
Better solution: r-family (memory optimized) instead of m-family. r7i.xlarge has the same vCPU as m7i.xlarge but 2x the memory.
A real cost comparison
Take a workload that runs continuously on 10 instances. CPU utilization is consistently 60%, with some headroom for spikes. Compare three options:
Stay on 10 × m5.xlarge:
- $140.16/month × 10 = $1,401/month
- Performance: baseline
Migrate to 10 × m7i.xlarge:
- $147.17/month × 10 = $1,471/month
- Performance: ~35% faster
- Could likely shrink to 8 instances at same workload: $1,177/month
Migrate to 10 × m7g.xlarge (Graviton):
- $119.14/month × 10 = $1,191/month
- Performance: similar to m7i, sometimes better for ARM64-native workloads
- Could likely shrink to 8 instances: $953/month
Best case: migrating to m7g with right-sizing cuts the bill from $1,401 to $953, a 32% reduction. Worst case (m7g doesn't work for your stack): m7i with right-sizing still saves 16%. Both pay back within one billing cycle.
What about Reserved Instances?
Reserved Instances complicate the analysis. If you have 1-year RIs on m5.xlarge, you've locked in 30-50% off m5 prices. The headline comparison flips:
- m5.xlarge with 1yr no-upfront RI: ~$98/month per instance
- m7i.xlarge on-demand: $147/month per instance
For the duration of the RI, staying on m5 is cheaper. Re-evaluate when the RI expires. The decision becomes: renew RIs on m7i (or m7g if your workload supports it) when the existing m5 RIs run out.
Compute Savings Plans add flexibility. A Compute Savings Plan applies to any compute (EC2, Lambda, Fargate, m5, m7i, m7g, etc.) at the same discount, so you can migrate instance families without losing the discount. For migrations spanning multiple instance families, Compute Savings Plans are usually a better choice than instance-specific RIs.
Checking your own utilization
Before migrating anything, look at CloudWatch CPU utilization for your existing instances. Three patterns:
- Average <30%, p99 <60%. You're over-provisioned. Downsize one size before considering family migration. The savings from t-shirt-size reduction usually exceed the savings from family migration.
- Average 40-70%, p99 80-95%. Well-utilized. Family migration to m7i or m7g delivers genuine price-performance gains.
- Average >70%, p99 hitting 100%. Under-provisioned. Upsize before workload starts impacting customers. New family plus larger size is the path forward.
For automated suggestions, run c3x recommend --path . on your Terraform. It flags instance generation upgrades and the expected savings per resource.
FAQ
Is m7i actually cheaper than m5 for the same workload?
The hourly rate is similar (m7i is ~5% more than m5 per hour at the same size). The savings come from price-performance: m7i delivers 15-20% better performance per dollar than m5 according to AWS benchmarks and our own testing. For workloads that complete tasks faster on m7i, total instance-hours drop, lowering the bill. For idle or fixed-duration workloads, the slightly higher hourly rate means a slight cost increase, but those workloads usually have better options like t-series or Spot.
Should I just use Graviton (m7g) instead?
If your workload runs on ARM64 (Go, Python, Node, Java, most modern stacks), m7g is roughly 20% cheaper than m7i with similar performance. Always evaluate Graviton first. If you have x86-only workloads or legacy binaries, m7i is the modern Intel default.
Why is m6i still around if m7i exists?
AWS keeps older instance families available for years after newer ones launch. m6i is sometimes available in regions where m7i isn't, or in availability zones where m7i capacity is constrained. For new workloads in m7i-available regions, prefer m7i. If you're already on m6i and migration to m7i is non-trivial, the upgrade isn't urgent.
When does m5 still make sense?
Almost never for new workloads. m5 is essentially obsolete for general-purpose compute. The only scenarios are: 1) workloads pinned to specific m5 features that aren't in newer families (rare), 2) Reserved Instance commitments still running on m5 where the RI savings exceed the m7i performance gain, 3) third-party software with version-specific licensing that prevents migration. Most teams should migrate to m6i or m7i.
What about m5n, m5dn, m6in, m7i-flex?
The suffixes are specialized: 'n' adds enhanced networking (100 Gbps), 'd' adds local NVMe SSD storage, 'flex' is m7i with a cheaper rate in exchange for variable CPU (similar to T-series but for memory-balanced workloads). For most workloads, the plain m-family is right. Add suffixes only when the specific capability matters.
How does pricing change across regions?
Significantly. us-east-1, us-east-2, us-west-2 are AWS's cheapest regions. Eu-west-1 (Ireland) is similar. Other EU regions are ~5-10% more. Asia Pacific is 15-25% more. South America is 30-40% more. The same m7i.xlarge that costs $0.2016/hour in us-east-1 costs $0.275/hour in ap-southeast-1 (Singapore). Region choice can drive bigger savings than instance family choice.
Putting it into practice
The migration checklist:
- Inventory all m5 and m6i instances with
aws ec2 describe-instances. Group by instance type and tag. - Check ARM64 readiness for each workload. Container? Multi-arch image. Compiled binary? Cross-compile. Runtime? Usually fine.
- For ARM64-ready workloads: migrate to m7g. Test in staging, deploy to production with rolling replacement.
- For x86-only workloads: migrate to m7i. Same Terraform change, same testing.
- Re-evaluate sizing post-migration. m7i often lets you drop one size (e.g., m7i.large where you previously needed m5.xlarge).
- Run
c3x diffin CI to verify the cost change matches expectations before merge.
For details on EC2 cost dimensions, the aws_instance catalog page has everything. For the broader cost-estimation workflow, see how to estimate AWS costs from Terraform.
Share this post
Try C3X on your own Terraform
Free and open source. No API key required. One command to install, one command to estimate.