CostMonStart free
Cloud costs

Cut AWS Costs Without Slowing Down Engineering

Every AWS bill has a few dollars in it that nobody would choose to spend if they were looking straight at them. The trouble is almost nobody looks straight at them: the bill lands a month after the spend happened, spread across hundreds of line items, and by the time it’s readable the engineering decisions that drove it are old news. Cost control on AWS isn’t about austerity. It’s about visibility early enough to act, and a short list of levers that don’t trade dollars for velocity. Below is that list, roughly in order of effort-to-payoff.

Start with what’s simply idle

Before you touch a single instance type, find the resources that are running and costing money while doing nothing useful:

  • Unattached EBS volumes. Every terminated instance can leave its volume behind, still billing by the gigabyte-month, forever, until someone notices.
  • Idle load balancers and NAT gateways. NAT gateways in particular charge both an hourly rate and a per-GB processing fee. Easy to miss, expensive to leave running against a subnet nothing uses anymore.
  • Old snapshots and AMIs. Snapshot chains from a decommissioned pipeline tend to outlive it by months, unnoticed.
  • Dev/staging environments that never sleep. If a dev cluster is sized and billed like production but only used nine hours a day, five days a week, you’re paying full-time for part-time work.

None of this requires a redesign. It requires someone to look, on a schedule, and a way to see the “orphaned” category as its own line rather than buried inside “EC2” or “EBS” in aggregate. This is the single highest ratio of savings-to-effort available on almost any AWS account, and it’s also the easiest to let slide. None of these resources are actively hurting anything; they’re just costing money, day after day, without anyone noticing.

Rightsize before you commit

Reserved Instances and Savings Plans are a commitment against your current shape of usage. Committing before rightsizing means locking in the waste along with the workload. Pull actual CPU, memory, and network utilization for your steady-state fleet. Most teams find a meaningful share of instances provisioned two sizes larger than anything they’ve ever needed, usually because “we’ll grow into it” felt safer than a follow-up ticket that never got filed. Rightsize first, then commit; the commitment is more accurate and the discount applies to a smaller, truer number.

Savings Plans vs. Reserved Instances

Once usage is stable, the discount question is really: how much flexibility do you want to give up for how much discount?

  • Reserved Instances are tied to instance family and region (or fully convertible, at a lower discount). They reward workloads that don’t move much, like a fixed-size database tier.
  • Savings Plans commit to a dollar-per-hour spend rather than a specific instance shape, and apply automatically across instance families, sizes, and even Fargate/Lambda in the case of Compute Savings Plans. Slightly lower ceiling discount than an inflexible RI, but far less risk of buying a commitment your architecture outgrows in six months.

For most teams past their first year, a layered approach works best: a Compute Savings Plan sized to your true steady-state floor, with anything above that floor left on-demand or spot. Nobody needs to get this perfect on day one. It’s worth revisiting quarterly as usage shifts, rather than treating it as a one-time purchase.

Before you commit, run the numbers both directions: the commitment discount calculator shows the break-even utilization below which a commitment costs more than staying on-demand, and the stranded spend if usage drops after you buy it.

None of this applies cleanly once the fleet in question is a Kubernetes cluster. A node’s bill and a pod’s request are two different accounting systems layered on top of each other. If that’s your fleet, the Kubernetes cost allocation & idle capacity calculator splits the node bill into used, workload idle, cluster idle, and system-reserved before you touch a single request.

Storage tiering is compounding, not one-time

Storage cost problems are sneaky because they compound silently: nothing about an S3 bucket, on any given day, looks expensive. But data that’s written once and rarely read is what lifecycle policies exist for. Moving objects from Standard to Infrequent Access to Glacier as they age turns a bucket that grows forever into one whose marginal cost per byte keeps falling. The same logic applies to EBS snapshots and RDS backups aging past their useful recovery window. If you haven’t set a lifecycle policy on your largest buckets, that’s usually the single biggest unclaimed discount sitting in a cloud bill, because it requires zero application changes, just a policy, set once.

Egress is the tax nobody budgets for

Data transfer is the line item most likely to surprise a team that’s otherwise disciplined about compute, because it scales with product success rather than with infrastructure decisions: more users, more egress, more bill. If a cryptic code like NatGateway-Bytes or DataTransfer-Regional-Bytes is what sent you looking for this post, the AWS Bill Decoder is the fastest way to translate it. A few levers that move egress itself:

  • CDN in front of anything public. Every asset served from a caching edge is an asset that didn’t cross a paid egress boundary.
  • Same-region traffic where possible. Cross-region and cross-AZ transfer both carry a cost that same-AZ, same-region traffic doesn’t.
  • Compress before you transfer. Obvious, frequently skipped for internal service-to-service traffic that “isn’t the hot path.”

The part that keeps it fixed

Every lever above is well documented, and most FinOps teams already know the list. The reason bills still creep is rarely lack of knowledge. It’s that AWS Cost Explorer shows the aggregate, weeks after the spend happened, in AWS’s categories rather than yours. By the time a rightsizing opportunity or an idle NAT gateway is visible in the console, it’s had a month to compound.

That lag is the gap CostMon is built to close: it pulls your AWS Cost Explorer data on a schedule, normalizes it alongside whatever else you run, and gives you trends and breakdowns you can watch continuously instead of reconstructing once a month from a CSV. Seeing the idle-resource category as its own line, every day, is what turns “we should really clean that up” into something that happens.

None of this is about spending less on infrastructure that’s earning its keep. It’s about not paying for infrastructure that isn’t, and knowing the difference before the invoice tells you.

A rate you looked up will change again.

Provider pricing pages change without notice. CostMon tracks the bill that pays for it.

Esc