Most AWS bills have 20–40% waste hiding in plain sight. Not in exotic services. Not in complex architectural decisions. In the boring, unglamorous stuff: over-provisioned instances, idle resources left running, and purchasing decisions that were never revisited after the initial setup.
Here’s a systematic approach to finding and eliminating that waste — most of which can be done in a week.
Step 1: Right-Size Your EC2 Instances (Biggest Win)
EC2 right-sizing is consistently the largest cost reduction opportunity for most AWS accounts. The typical pattern: an engineer provisions an m5.4xlarge for a workload that peaks at 15% CPU, then nobody revisits the instance type because “it works.”
How to find candidates:
Open AWS Cost Explorer and filter by service: EC2. Sort by cost. Then open CloudWatch and pull average CPU utilisation for your top 10 costliest instances over the last 30 days.
Any instance consistently below 30% average CPU is a right-sizing candidate. A move from m5.4xlarge ($0.768/hr) to m5.xlarge ($0.192/hr) is a 75% reduction for that instance.
What to look for:
- Average CPU < 30% sustained → downsize instance family
- Average CPU < 10% → consider whether this workload needs to run constantly at all
- Memory-intensive workloads with low CPU → consider
r5series instead of over-provisioningm5
Realistic saving: 15–25% of EC2 spend for most accounts.
Step 2: Hunt Down Idle Resources
Every AWS account accumulates idle resources over time. Engineers spin things up to test something, forget to clean up, and the meter keeps running.
The highest-value idle resources to find:
Unattached EBS volumes. Go to EC2 → Volumes → filter by “Available” state. Anything not attached to a running instance is costing you money for nothing. Snapshot them if you’re not sure, then delete.
Old snapshots. EBS snapshots accumulate forever unless you have a lifecycle policy. Go to EC2 → Snapshots and sort by creation date. Snapshots older than 90 days that aren’t referenced by any AMI are almost always safe to delete.
Idle Elastic Load Balancers. An ALB with no registered targets and no traffic still costs ~$16/month. Go to EC2 → Load Balancers and look for any with 0 active connections over 30 days.
Unused Elastic IPs. AWS charges $3.60/month for each Elastic IP not associated with a running instance. EC2 → Elastic IPs → filter by unassociated.
Realistic saving: $50–$500+/month depending on account age. Older accounts tend to have significantly more debris.
Step 3: Reserved Instances vs Savings Plans
If your EC2 spend has been consistent for 6+ months, you’re almost certainly leaving money on the table by paying on-demand prices.
The basics:
- 1-year Reserved Instances or Savings Plans: 30–40% off on-demand
- 3-year: up to 60% off
- No upfront, partial upfront, or full upfront payment options
Which to choose:
- Compute Savings Plans are the most flexible. They apply automatically to any EC2 instance regardless of family, size, region, or OS. Good if you’re not sure about future instance types.
- EC2 Instance Savings Plans offer deeper discounts but lock you to a specific instance family in a specific region.
- Reserved Instances offer the deepest discounts but are least flexible.
The key insight: You don’t need to reserve 100% of your capacity. Start by identifying your minimum baseline usage — the instances that run 24/7 regardless of traffic — and cover just those. Then let on-demand handle peaks.
Realistic saving: 30–40% on the compute you choose to cover, which typically represents 50–70% of your total EC2 bill.
Step 4: Turn Off Dev Environments at Night
This is embarrassingly obvious but surprisingly rare: dev and staging environments don’t need to run at 3am on a Saturday.
A dev environment running 168 hours/week vs 40 hours/week (9am–7pm weekdays) reduces costs by 76%. For a modest dev environment costing $500/month, that’s $380 back.
How to implement:
AWS Instance Scheduler is the standard approach. You define schedules in DynamoDB and tag instances accordingly. Alternatively, Lambda functions triggered by EventBridge rules work fine for simpler setups.
For RDS, Aurora Serverless v2 auto-pauses when idle. For non-serverless RDS, consider stopping DB instances on a schedule — AWS allows you to stop RDS instances for up to 7 days at a time.
Realistic saving: 50–70% of dev/staging compute costs.
Step 5: Use CloudWatch to Find Specific Waste
CloudWatch metrics tell you what’s actually happening vs what you provisioned for.
Three metrics worth pulling for every major service:
- CPUUtilization — for EC2, RDS, ElastiCache. Consistently < 20% = over-provisioned.
- DatabaseConnections — for RDS. If max connections is 5 and you provisioned for 500, you’re paying for capacity you’ll never use.
- RequestCount — for ALBs. Zero for 30 days = likely orphaned.
Practical approach:
Set up CloudWatch alarms on these metrics with a threshold that represents “probably idle.” Route alerts to a Slack channel. When an alarm fires and nobody acts on it within 30 days, that resource goes on the cleanup list.
Putting It All Together
Here’s a realistic week-long approach:
- Day 1: Pull CloudWatch CPU metrics for all EC2 instances. Identify right-sizing candidates.
- Day 2: Audit idle resources — unattached EBS, old snapshots, idle ELBs, unused EIPs.
- Day 3: Analyse 6-month EC2 spend pattern. Buy Compute Savings Plans for stable baseline.
- Day 4: Implement instance scheduling for dev/staging environments.
- Day 5: Set up CloudWatch alarms on the idle-resource metrics to catch future drift.
Most teams that go through this process find 25–35% savings within the first month. The EC2 right-sizing and reserved instances alone typically account for most of the gain.
The harder part isn’t finding the savings — it’s making time to act on them. That’s why automated tooling that surfaces these opportunities continuously matters more than a one-off audit.
Xplorr automatically surfaces right-sizing opportunities, idle resources, and reserved instance candidates for AWS, Azure, and GCP. Request beta access — free for early teams.
Share this article
Ready to control your cloud costs?
Join early teams getting real visibility into their AWS, Azure, and GCP spend.
Request Beta Access