EC2 Cost Optimization Guide
Most AWS accounts overspend on EC2 by 30-40%. Here's a practical playbook to find and eliminate waste without sacrificing performance.
The Four Pillars of EC2 Savings
Right-Sizing
Match instance type and size to actual workload needs. The #1 source of EC2 waste.
Idle Detection
Find and eliminate instances that are running but doing nothing useful.
Scheduling
Stop dev/test instances outside business hours. Simple but often overlooked.
Commitment Discounts
Use Reserved Instances, Savings Plans, or Spot for predictable or flexible workloads.
📐 Right-Sizing Step by Step
Enable CloudWatch detailed monitoring
Basic monitoring (5-min intervals) is free but not enough. Enable detailed monitoring (1-min) for accurate CPU data. Use CloudWatch Agent for memory and disk metrics — these are not collected by default.
aws cloudwatch put-metric-alarm --alarm-name "LowCPU" --metric-name CPUUtilization --namespace AWS/EC2 --statistic Average --period 86400 --threshold 10 --comparison-operator LessThanThreshold --evaluation-periods 14Analyze 2+ weeks of data
Don't right-size based on a single day. Look at at least 14 days to capture weekly patterns. Check peak usage, not just average — you need headroom for spikes.
Use AWS Compute Optimizer
Free service that analyzes your CloudWatch metrics and recommends optimal instance types. It considers CPU, memory, network, and storage. Enable it account-wide.
Downsize incrementally
Don't jump from m5.4xlarge to m5.large in one step. Go one size down, monitor for a week, then repeat. This avoids performance incidents.
👻 Detecting Idle Instances
An instance showing multiple signals below is likely idle and should be investigated.
| Signal | Threshold |
|---|---|
| CPU Utilization | < 5% average over 7 days |
| Network In/Out | < 1 MB/day combined |
| Disk Read/Write Ops | 0 ops over 7 days |
| No SSH/RDP connections | No login activity for 30+ days |
| No attached Load Balancer | Instance not serving traffic |
🕐 Instance Scheduling
Use AWS Instance Scheduler, EventBridge rules, or simple Lambda functions to start/stop instances on a schedule.
Dev/Test environments
Run only during business hours (Mon-Fri, 9am-6pm). That's 45 hrs/week vs 168 hrs/week.
Staging environments
Run during extended hours (Mon-Fri, 8am-10pm) to cover different time zones.
Demo environments
Spin up on-demand before demos, tear down after. Use Infrastructure as Code for quick provisioning.
💰 Choosing a Pricing Model
Is the workload steady and predictable?
Can it tolerate interruptions?
Does it run on a schedule?
Quick Wins
Switch to Graviton
ARM-based instances are up to 40% cheaper with equal or better performance. Most Linux workloads work without changes.
Read more →Tag everything
Without tags you can't attribute costs. Enforce tagging with AWS Organizations SCPs. Minimum: Environment, Team, Project.
Clean up old snapshots
EBS snapshots accumulate silently. Review and delete snapshots older than 90 days that aren't tied to AMIs you use.
Release unused Elastic IPs
Unattached Elastic IPs cost $0.005/hr ($3.60/month each). Small but adds up across accounts.
Use Cost Explorer daily
Set up daily cost anomaly detection in AWS Cost Explorer. Catch runaway instances before they become a surprise bill.
Consider Spot for fault-tolerant workloads
Up to 90% savings for batch jobs, CI/CD, and stateless workers.
Read more →Find your savings potential
Compare on-demand, reserved instances, savings plans (1-year & 3-year with all payment options), and spot prices for any instance type across all regions.
Open Calculator