Skip to content
← Writing
DiagnosticFinOps10 min

Why your AWS bill keeps climbing after launch (and what to fix first)

Five root causes I see across every engagement, ranked by how often they show up in a real production audit.

By Rahul Ladumor

Most AWS bills don't break in one big jump. They climb. A few percent every month, then someone notices the finance ticket. Then the engineering team gets pulled in. Then someone says "let's right-size EC2" and the meeting ends.

In every cost engagement I've run, the climb is almost never one problem. It's five problems, all small, compounding. This article walks through the five I see in nearly every audit, the order I look at them, and what actually works to bring spend down without breaking production.

Why bills climb after launch

At launch, the architecture is small enough that nobody pays attention to cost surface. Logs are at default retention. Lambda is at default memory. Auto Scaling Groups are set to "what worked in staging." Storage is in one tier. There's no tag policy. There's no owner per resource.

Then traffic grows. The system handles it. That's why people remember the launch as a success. But every default that survived launch is now running in production at scale. And the bill grows with it.

Here are the five causes, in the order I check them.

1. Cost has no owner

This is almost always cause zero. If you open Cost Explorer and you can't say in one sentence "this $X is for team Y's workload," you have an ownership problem before you have a cost problem.

Without tags and per-team allocation, every cost conversation becomes a meeting. Engineers don't know which line items are theirs. Finance doesn't know who to ask. So the bill grows in the gap.

The fix: turn on an SCP (Service Control Policy) at the Org level that blocks resources without required tags (team, cost-center, env). Run it in audit mode for 30 days. Backfill tags on existing resources. Then enforce.

After that you can actually have the next four conversations.

2. Logs and traces grew silently

CloudWatch Logs is the cost surface nobody looks at because it doesn't show up under "EC2" or "Lambda." It shows up under "CloudWatch."

Default log retention is "Never expire." On a busy Lambda or ECS workload, that compounds fast. I have seen CloudWatch Logs quietly eat close to a third of a bill, with the large majority of those logs beingINFOlines from libraries.

What to check:

  • Default retention on every log group: set to 30 days, override per group
  • Lambda Powertools / structured logging: drop noisy fields server-side
  • X-Ray sampling: 100% in staging is fine; 5-10% in prod is enough
  • VPC Flow Logs: destination, retention, and whether you actually query them

3. Retries and idle compute

Two patterns hide here. Both look "fine" in dashboards.

Retry storms. A flaky downstream causes Lambda to retry three times by default. SQS retries multiply that. EventBridge retries again. A single bad path can multiply your invocation count by 10x for the duration of an outage, and you pay for every invocation.

Idle compute. EC2 instances spun up for a one-off migration in 2024. RDS dev clusters that nobody stopped. Aurora Serverless v1 with auto-pause off. ECS services with desired count = 4 that handle the same load as 2.

The fix: Lambda destinations for failures (not retries forever). DLQs on every SQS queue with an alarm. Trusted Advisor's idle EC2 report: run it monthly. Compute Optimizer recommendations applied to ASGs.

4. Storage tier mistakes

S3 has six storage classes. Most teams use one. Standard. Forever.

If you're storing more than 1 TB and not using Intelligent-Tiering, you are paying for hot access on cold data. Same goes for EBS volumes: gp3 is cheaper than gp2 for the same performance, and almost nobody migrates.

Quick wins I look for:

  • S3 lifecycle policies on log buckets: Standard → IA → Glacier
  • S3 Intelligent-Tiering on any bucket >1 TB
  • EBS gp2 → gp3 migration (same performance, cheaper)
  • RDS snapshots from deleted databases (yes, they still cost)
  • Unused EBS volumes left behind by terminated instances

5. Egress and cross-AZ data

The last cause is the most painful because it requires architecture changes, not config flips. Data transfer is the line item that grows with traffic, and AWS charges it three ways:

  • Cross-AZ: traffic between AZs in the same region. Real cost on a multi-AZ ECS or RDS workload.
  • Cross-region: replication or DR traffic.
  • Internet egress: traffic out to users, including responses to API calls.

CloudFront in front of S3 reduces egress 10-100x. PrivateLink instead of public endpoints removes NAT Gateway data costs. AZ-aware service placement reduces cross-AZ traffic for chatty services.

How I diagnose this in a real audit

When I run a cost engagement, the first three days are not about optimization. They are about visibility.

  1. Day 1: Pull Cost Explorer 90-day data by service, tag, and account. Pull Trusted Advisor reports. Run the CUR into Athena for line-item drill.
  2. Day 2: Map untagged spend. Identify the top 10 cost line items. Cross-reference with engineering owners.
  3. Day 3: Walk each top-10 with the owning team. Tag, confirm intent, mark for review.

Only after that do I propose changes. Anything earlier and you risk right-sizing something a team is about to ship into.

What fixes actually work

Across the engagements I've run, this is the rough order of impact:

LeverTypical savingRisk
Tag enforcement + idle resource cleanup10-25%Low
Log retention + observability tier tuning5-15%Low
Storage lifecycle + gp3 migration3-10%Low
Right-sizing compute10-20%Medium
Savings Plans / RI on stable baseload15-30% on covered spendMedium (lock-in)
Cross-AZ / egress redesign5-20%High (touches code)

Most teams skip the first three and jump to Savings Plans. That's why their bill keeps climbing: they locked in the waste.

The right order is: visibility first, cleanup second, right-sizing third, commitments last. Architecture changes (egress, cross-AZ, caching) come in as a separate engagement once the obvious wins are booked.

One real number: across past freelance work, this approach delivered up to a 55% reduction in combined client spend on stable workloads. Per-client savings ranged 25-55%. Spiky / event-driven workloads saw less because they're already close to right-sized.

Next step

Have the same problem on your stack?

Send the architecture, AWS bill concern, deploy pain, or GenAI reliability issue. I'll find the first real bottleneck and propose a small, reversible fix.

FAQ

What's the single fastest fix for a climbing AWS bill?

Tag enforcement plus a 7-day idle-resource audit. You find the worst offenders inside a week. Right-sizing comes after: too risky to do first without visibility.

How much can a one-time AWS cost review typically save?

Across past engagements, per-client savings range 25-55% on stable workloads (up to 55% on the heaviest). Spiky workloads see less.

Should I buy Savings Plans first or right-size first?

Right-size first. Savings Plans lock spend on the resources you have. Buying them before right-sizing locks in the waste.

How do I know if the bill problem is architecture or operations?

If the bill grows linearly with traffic, it's usually operations (idle resources, log retention, cross-AZ). If it grows non-linearly, it's architecture (N+1 calls, retry storms, cache miss spirals).

What's the difference between Cost Explorer and a CUR Athena query?

Cost Explorer is a rolled-up view, good for trends. CUR (Cost and Usage Report) into Athena gives you line-item drill-down: exact resource, exact hour, exact cost. You need both.

Related reading

#AWS#FinOps#Cost optimization#Production
Rahul Ladumor

Rahul Ladumor

Principal Cloud & AI Platform Architect. AWS Professional certified, 4x AWS Community Builder. I work with teams that have real users, real AWS bills, and real production pressure.

About Rahul →