How We Cut Our AWS Bill by 40% Without Touching Performance
A walkthrough of the audit, the low-risk wins we shipped first, and the two changes that actually moved the needle — right-sizing instances wasn't one of them.
A client came to me with a familiar problem: their AWS bill had grown 3x over eighteen months, roughly in line with their user base, and nobody could say with confidence where the money was actually going. Finance wanted a number to plan around. Engineering wanted to keep shipping without a cost review turning into a six-week side quest. Both were reasonable asks that usually fight each other — this is the process that made them stop fighting.
Start with visibility, not cuts
The instinct when a bill is too high is to start right-sizing instances immediately. Resist it. Without a cost breakdown by service, environment, and team, you're optimizing blind — and the first thing you shrink is rarely the thing actually costing money.
We spent the first three days purely on visibility: enabling AWS Cost Explorer with proper tagging, backfilling tags on untagged resources with a Lambda-based sweep, and building a Grafana dashboard fed by the Cost and Usage Report in S3. That dashboard alone paid for itself — it surfaced $4,200/month in orphaned EBS volumes and unattached Elastic IPs that nobody had noticed because nothing was actively broken.
If you can't attribute cost to a team or service within a few clicks, you don't have a cost problem yet — you have a visibility problem, and it's cheaper to fix first.
The quick, low-risk wins
These shipped in the first week, with essentially zero risk to production:
- Orphaned resources. Unattached EBS volumes, idle Elastic IPs, and old AMI snapshots nobody referenced anymore — a recurring monthly cleanup job now catches these automatically.
- S3 lifecycle policies. Logs and build artifacts sitting in S3 Standard for years, moved to Infrequent Access after 30 days and Glacier Deep Archive after 180. This alone was the second-largest single saving.
- Non-production schedules. Staging and dev environments running 24/7 for no reason — an EventBridge rule now stops them outside business hours, which cut compute spend on those accounts by roughly 65%.
The two changes that actually moved the needle
The quick wins were satisfying but small relative to the total bill. Two changes accounted for most of the 40% reduction, and neither was "make the servers smaller."
1. Compute Savings Plans, sized conservatively
On-demand pricing was the single biggest line item. Rather than reserved instances tied to specific instance families, we committed to a 1-year Compute Savings Plan sized at 70% of the trailing 30-day baseline usage — deliberately conservative, so normal traffic growth wouldn't blow past the commitment and leave on-demand spend stacking on top of it. That one change covered roughly 18 percentage points of the total 40% reduction.
2. Collapsing three "just in case" environments into one
The team had QA, staging, and a "pre-prod" environment that had quietly become a fourth production-adjacent environment nobody wanted to delete. After confirming with the team that pre-prod hadn't been used for its original purpose in over four months, we merged its responsibilities into staging with proper environment variables and feature flags instead of a fully separate account. That's infrastructure that doesn't need optimizing because it no longer exists.
What we deliberately didn't touch
We left the production database tier untouched. It was already right-sized from a previous engagement, and further optimization there had a worse risk-to-reward ratio than the changes above. Cost work has diminishing returns fast — chasing the last 5% is rarely worth the engineering hours or the risk, especially on anything customer-facing.
Takeaways if you're starting this yourself
- Get visibility before you cut anything — tagging and a real cost dashboard first.
- Ship the zero-risk wins immediately; they build momentum and buy-in for the bigger changes.
- Look for commitment-based discounts (Savings Plans/Reserved Instances) sized conservatively against your real baseline, not your peak.
- Ask whether an environment or service needs to exist at all before optimizing it.
- Know when to stop — not every dollar is worth the engineering time to chase.
None of this required touching application code or degrading performance for a single end user. It was almost entirely a visibility and commitment-structure problem, which is true for most cloud bills that have grown organically alongside a growing team.
On this page
About the author
Runs cloud cost audits and migrations for small-to-mid-size engineering teams. Founder of DB Analytica.
More about mecontact.sh
Think your cloud bill has room to shrink?
A cost audit like this one usually takes 1–2 weeks and pays for itself in the first month.
