The Problem
Cloud cost optimization generates a lot of conference talks and very little change. Most cost work fails not because the techniques are wrong but because there’s no plan. The cost team identifies opportunities. Engineering disagrees about priority. Finance asks for a number by Friday. Nothing structural improves.
A 30-day plan changes that. Four weeks, four targeted activities. By the end, you’ve cut 20-40% of monthly spend in most environments without touching a single application code path.
The Approach
Week 1: Inventory
You can’t cut what you can’t see. Week 1 is purely investigative.
Day 1-2: Tag what’s missing. Run a tagging audit across every account. Anywhere a resource has no owner, cost-center, or environment tag, find the responsible team. If no team owns it, mark it as a candidate for elimination. Most environments find 10-15% of resources are untagged, and a meaningful fraction of those are abandoned.
Day 3-4: Pull the cost-by-service report. AWS Cost Explorer, broken down by service for the trailing 90 days. Print it. Highlight the top 10 services by spend. Those ten lines are 80%+ of your bill. Anything you don’t recognize on that list is an investigation.
Day 5: Map cost to service. For each top-10 service, identify which application or workload is responsible. If you can’t map a cost line to a workload, that’s a finding. Usually a forgotten experiment, a deprecated product line, or a misconfigured backup.
Week 1 output: a tagged inventory, a cost-by-service report, and a list of resources or services with no clear owner.
Week 2: Eliminate
The easiest cost savings are resources you can simply turn off. Order matters: handle the obvious cases first so you have momentum and signal for the team.
Idle EBS volumes. Run a query for any EBS volume in available state (not attached to any instance). These are 100% waste. Snapshot them if they’re under 90 days old; delete the volume. Common AWS environments find a few percent of EBS spend in idle volumes.
Unattached Elastic IPs. AWS charges per hour for EIPs that aren’t attached to a running instance. Find them, release them. Negligible per-EIP cost, but the principle matters: zero-tolerance for paying for nothing.
Orphaned snapshots. Snapshots whose source volume has been deleted, or snapshots more than two years old with no recent restore. The retention policy you’d set today is “keep the last 30 days plus the last day of every month for a year.” Apply it retroactively.
Idle load balancers. ALBs and NLBs with zero traffic for 30 consecutive days. Either find why they exist, or delete them. The cost is small per-LB but the count grows fast.
Old AMIs and ECR images. AMIs older than 90 days that aren’t referenced by any launch template. ECR images older than 180 days that aren’t deployed anywhere. Both accumulate silently.
Dev environments running 24/7. Schedule dev/staging accounts to shut down outside business hours. Most teams find dev environments can run 50 hours/week instead of 168 with no impact on engineer velocity.
Week 2 output: a list of resources deleted, with rough monthly savings per category. Realistic recovery in this week alone: 5-15% of total bill.
Week 3: Right-size
Now the work gets more careful. You’re modifying running infrastructure.
EC2 instances. AWS Compute Optimizer surfaces over-provisioned instances based on CloudWatch metrics. For any instance running below 20% sustained CPU and below 40% sustained memory, propose a one-size-down change. Roll out one at a time during low-traffic windows; monitor for a week before declaring success.
RDS instances. Same idea, but cautiously. Compute Optimizer covers RDS too. The riskier change is gp2 → gp3 storage. Almost always strictly cheaper and faster, but requires a maintenance window.
Lambda memory. Teams over-provision Lambda memory because it’s the only lever for CPU. Use the AWS Lambda Power Tuning tool to find the cost-optimal memory setting for each function. Often 256MB or 512MB outperforms 1024MB on both cost and latency.
EBS volume types. Migrate gp2 to gp3 universally. gp3 is faster, lets you provision IOPS independently of size, and is roughly 20% cheaper at the same provisioned size. There is no legitimate reason to keep new gp2 volumes in 2025+.
ARM where compatible. AWS Graviton (ARM) instances are ~20% cheaper than x86 equivalents and often faster for many workloads. Anywhere your code runs on a managed runtime (Lambda, Fargate, App Runner) the switch is one config change. For self-managed instances, the work is rebuilding the AMI, which is a week of effort that recovers itself in two months.
Week 3 output: a list of rightsizings made, with metrics confirming workload health. Realistic recovery: 10-20%.
Week 4: Commit
By week four, the workload mix has stabilized. Now you commit to it.
Savings Plans. Use the AWS Cost Explorer recommendations engine to identify the “Compute Savings Plan” coverage that matches your steady-state spend on EC2, Fargate, and Lambda. The standard recommendation is to cover 70-80% of your baseline; the remaining 20-30% stays flexible for growth or migration.
Reserved Instances for RDS. RDS doesn’t have Savings Plans (yet); RIs are the equivalent. One-year, no-upfront commitments give ~30% off list with minimal lock-in risk.
Spot instances for burst. If you have batch workloads or any compute that can tolerate interruption, run them on spot. Discounts of 70-90% off on-demand.
Sanity-check the savings. Pull next month’s projected spend versus this month. Confirm it dropped. If it didn’t, your savings work was offset by growth. That’s fine, but document it so the cost story is clear to leadership.
Week 4 output: signed Savings Plans, RI purchases, a projected-spend chart showing the reduction.
The Template
Below is the weekly checklist. Each row is a single action with a clear “done” state. Run through it sequentially.
Week 1: Inventory
- Tagging audit complete; untagged resources flagged
- Cost-by-service top-10 list produced
- Cost-to-workload mapping complete; orphan workloads identified
Week 2: Eliminate
- All idle EBS volumes deleted (after snapshot)
- All unattached EIPs released
- Snapshots older than retention policy deleted
- Load balancers with zero traffic for 30+ days investigated or deleted
- AMIs / ECR images outside retention deleted
- Dev environment shutdown schedules in place
Week 3: Right-size
- Compute Optimizer recommendations triaged
- EC2 right-sizings rolled out (10+ instances)
- RDS gp2 → gp3 migrations complete
- Lambda memory tuned on top-spend functions
- ARM migration assessed for compatible workloads
Week 4: Commit
- Savings Plan signed for steady-state EC2/Fargate/Lambda
- RDS RIs purchased for steady-state databases
- Spot adopted for batch / interruptible workloads
- Month-over-month spend reduction confirmed
Operating Notes
Run the cleanup quarterly, not once. The work compounds in both directions: environments accumulate waste, and your team forgets which knobs they turned. A 30-day cleanup every Q1 and Q3 keeps the bill close to its true workload cost.
Document the savings. Cost reductions get forgotten faster than cost increases. A one-page memo per cleanup, with the before/after numbers and the specific actions taken, builds the institutional memory that lets the next cleanup go faster.
The hard part is never the technique. It’s getting four weeks of focused work on a problem that doesn’t show up in product roadmaps.