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

1

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 14
2

Analyze 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.

3

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.

4

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.

SignalThreshold
CPU Utilization< 5% average over 7 days
Network In/Out< 1 MB/day combined
Disk Read/Write Ops0 ops over 7 days
No SSH/RDP connectionsNo login activity for 30+ days
No attached Load BalancerInstance not serving traffic

🕐 Instance Scheduling

Use AWS Instance Scheduler, EventBridge rules, or simple Lambda functions to start/stop instances on a schedule.

~65% off

Dev/Test environments

Run only during business hours (Mon-Fri, 9am-6pm). That's 45 hrs/week vs 168 hrs/week.

~50% off

Staging environments

Run during extended hours (Mon-Fri, 8am-10pm) to cover different time zones.

~85% off

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?

Yes →Reserved Instance or Savings Plan (up to 72% off)
No →Next question ↓

Can it tolerate interruptions?

Yes →Spot Instances (up to 90% off)
No →Next question ↓

Does it run on a schedule?

Yes →Instance Scheduler + On-Demand
No →On-Demand (optimize with right-sizing)
For a deep dive on commitments, see Savings Plans vs Reserved Instances.

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