EC2 Cost Optimisation
EC2 is the largest line item on most AWS bills. The good news is that it also has the most levers. Right-sizing, commitment pricing, Spot Instances, Graviton, and storage type all compound — applying all five can cut EC2 costs by 60–80% compared to a naive On-Demand setup.
The pricing baseline: what you’re starting from
Before optimising, it helps to understand what the same workload costs under each pricing model. Here’s a concrete comparison for an m5.large instance in us-east-1, running 24/7:
| Pricing model | Hourly rate | Monthly cost | Annual cost | Saving vs On-Demand |
|---|---|---|---|---|
| On-Demand | $0.096 | $70 | $840 | — |
| 1-year Savings Plan | $0.061 | $45 | $535 | 36% |
| 3-year Savings Plan | $0.038 | $28 | $333 | 60% |
| 1-year Reserved (all upfront) | ≈$0.050 | $37 | $440 | 47% |
| Spot Instance | ≈$0.028–0.035 | ≈$20–25 | ≈$250 | 65–70% |
At 10 instances, the difference between On-Demand and a 3-year Savings Plan is $507/month — $6,090/year — for no change in architecture. Just a pricing commitment.
Rightsizing: matching instance size to actual usage
The most common EC2 waste pattern is over-provisioning. Developers often provision large instances to avoid performance problems, then forget to revisit the sizing once the actual workload is established.
AWS Compute Optimizer analyses 14 days of CloudWatch CPU utilisation, memory, disk, and network metrics to recommend appropriately sized instances. To get recommendations:
aws compute-optimizer get-ec2-instance-recommendations \
--region us-east-1A typical finding: an m5.2xlarge (8 vCPU, 32GB RAM) running at 8% average CPU and 12% memory. Compute Optimizer recommends an m5.large (2 vCPU, 8GB RAM). The On-Demand price drops from $0.384/hr to $0.096/hr — a 75% reduction.
Before rightsizing, verify peak utilisation, not just average. A server that sits at 5% CPU normally but hits 90% during a monthly report generation run needs to stay at a size that handles the peak. Use CloudWatch metrics with the p99 percentile, not just the average.
See the dedicated rightsizing guide for a full walkthrough.
Savings Plans vs Reserved Instances
Both Savings Plans and Reserved Instances provide discounts in exchange for a 1- or 3-year commitment. The difference is flexibility:
Compute Savings Plans — commit to spending a minimum dollar amount per hour (e.g., $10/hr of compute). The discount applies to any EC2 instance regardless of type, size, OS, or region. Also applies to Lambda and Fargate. Maximum flexibility.
EC2 Instance Savings Plans — commit to a specific instance family in a specific region (e.g., m5 instances in us-east-1). Deeper discount than Compute Savings Plans, but if you move to c6g (Graviton), the plan no longer applies.
Standard Reserved Instances — locked to a specific instance type, size, region, and OS. Deepest discount, least flexibility.
Convertible Reserved Instances — can be exchanged for a different type within the same family. Moderate discount, moderate flexibility.
For most teams, Compute Savings Plans are the right choice. They don’t penalise you for rightsizing, moving to Graviton, or changing regions. The discount is slightly lower than Standard RIs, but the flexibility is worth it.
The key rule: only commit to what you know you’ll consistently use. If your stable baseline is 5 m5.large instances, buy Savings Plans for that amount. Use On-Demand or Spot for anything above that baseline.
Graviton instances: 20–40% savings, same performance
AWS Graviton processors (ARM-based) power the m6g, c6g, r6g, and newer m7g, c7g instance families. The pricing advantage is significant:
m5.large(Intel x86): $0.096/hrm6g.large(Graviton 2): $0.077/hr — 20% cheaperm7g.large(Graviton 3): ~$0.0816/hr — 15% cheaper, but often faster
For CPU-bound applications, Graviton 3 frequently delivers better performance-per-dollar than x86, even at the same price. AWS publishes benchmark comparisons for common workloads.
Graviton requires your application to be compatible with ARM64:
- Linux applications written in interpreted languages (Python, Node.js, Ruby, Java) typically work without changes
- Go, Rust, and most compiled languages work after recompiling for ARM64
- Containers need ARM64 images (multi-arch builds are now standard on most public images)
- Windows is not supported on Graviton
The migration path is: build your application image for ARM64, run it on a Graviton instance in a dev environment, validate it works, then deploy to production.
Spot Instances for fault-tolerant EC2 workloads
Spot Instances are unused EC2 capacity sold at steep discounts — typically 60–90% below On-Demand. The catch is that AWS can reclaim them with a two-minute warning.
EC2 workloads that work well on Spot:
- Batch data processing (can checkpoint and restart)
- CI/CD build runners
- Stateless web tier behind a load balancer with Auto Scaling (if one Spot node is reclaimed, the load balancer redistributes traffic)
- Machine learning training jobs that support checkpointing
EC2 workloads that should not run on Spot:
- Databases (state corruption risk)
- Long-running transactions that can’t tolerate interruption
- Any single-instance setup without redundancy
When using Spot in an Auto Scaling Group, diversify across multiple instance types and availability zones. If you request only m5.large Spot in one AZ, you may find unavailability periods. Requesting across m5.large, m5a.large, m4.large, and m6i.large across 3 AZs gives you much better availability.
See the Spot Instances for cost savings page for detailed configuration examples.
Stopping dev and test instances at night
Development and test environments don’t need to run 24/7. An m5.large dev instance running 8 hours/day, 5 days/week costs about 24% of running it continuously.
8 hr/day × 5 days/wk × 4.3 wk/month = 172 hours/month $0.096 × 172 = $16.51/month
Vs running continuously: $0.096 × 730 = $70.08/month
Saving: $53.57/month per instance.
AWS Instance Scheduler (an AWS solution, deployed via CloudFormation) handles start/stop scheduling automatically. Alternatively, a simple EventBridge rule can trigger a Lambda function to stop EC2 instances by tag at a scheduled time.
For RDS, the same principle applies. Stopping a development RDS instance overnight (RDS can be stopped for up to 7 days at a time) eliminates the instance-hour charges while retaining the data.
EBS volume optimisation: gp3 over gp2
If you have existing gp2 EBS volumes, migrating to gp3 saves 20% on storage costs with no performance loss for most workloads:
gp2: $0.10/GB/month, with IOPS that scale automatically with volume size (3 IOPS/GB, up to 16,000)gp3: $0.08/GB/month, with a baseline of 3,000 IOPS and 125 MB/s throughput regardless of size — and you can add more IOPS/throughput independently if needed
The migration requires no downtime. You can modify a volume’s type while it’s attached and in use:
aws ec2 modify-volume \
--volume-id vol-1234567890abcdef0 \
--volume-type gp3For a team with 50 EBS volumes averaging 200GB each (total: 10,000GB):
- gp2 cost: 10,000 × $0.10 = $1,000/month
- gp3 cost: 10,000 × $0.08 = $800/month
- Saving: $200/month for a one-time migration effort
Note: Savings Plans purchases take effect immediately after purchase and appear on your bill within hours. However, before purchasing, use the Savings Plans recommendations in the Cost Explorer console — AWS will show you the estimated hourly commitment needed to cover your current On-Demand usage and project the savings. Never buy Savings Plans based on intuition alone.
Common mistakes
- Buying Reserved Instances before rightsizing — If you buy RIs for 10 m5.2xlarge instances and then rightsize them to m5.large, your RIs no longer apply (unless you bought Convertible). Always rightsize first, then commit to a pricing plan.
- Using Spot for databases — A Spot interruption on a database instance can corrupt data or cause data loss. Databases should always run On-Demand or on Reserved Instances — never Spot.
- Not diversifying Spot Instance types — Requesting only one Spot instance type in one AZ means interruptions or unavailability affect all your Spot nodes at once. Diversify across types and AZs.
- Keeping gp2 volumes out of habit — gp3 is cheaper and more flexible. There is no good reason to continue using gp2 for new or existing volumes.
- Committing to more Savings Plans than your stable baseline — If you buy $20/hr of Compute Savings Plans but your consistent usage is only $12/hr, you’re paying for $8/hr of committed spend with nothing running against it.
Summary
- A 3-year Compute Savings Plan saves 60% over On-Demand; Spot Instances save up to 90% for interruptible workloads
- Compute Optimizer analyses CloudWatch metrics and recommends appropriately sized instances
- Graviton instances cost 15–20% less than equivalent x86 instances and often deliver better performance
- Stop dev and test instances at night — 8-hour workday usage costs about 24% of 24/7 usage
- Migrate gp2 EBS volumes to gp3: 20% cheaper with no performance reduction, zero downtime
- Rightsize before buying commitment pricing — committed to the wrong size is money wasted
- Diversify Spot Instance types and AZs to avoid simultaneous interruptions
Frequently asked questions
Should I use Reserved Instances or Savings Plans for EC2?
Savings Plans are generally better for most teams because they are more flexible. Compute Savings Plans apply to any EC2 instance type, region, and OS, as well as Lambda and Fargate. Reserved Instances give a slightly deeper discount but are locked to a specific instance type and region.
What are Graviton instances and how much do they save?
Graviton instances use AWS-designed ARM-based processors. They cost roughly 20% less than equivalent Intel x86 instances of the same generation. For applications already running on Linux that do not depend on x86-specific binaries, migrating to Graviton is one of the easiest cost reductions available.
Is gp3 actually cheaper than gp2?
Yes. gp3 costs $0.08/GB/month compared to gp2 at $0.10/GB/month — a 20% saving on storage. gp3 also offers configurable IOPS and throughput independently of size, whereas gp2 IOPS scale with volume size. For most workloads, gp3 is the right choice for all new volumes.