September 14, 2026 6 min read DevOps & cloud

How to Reduce Your AWS Bill Without Sacrificing Performance

A practical order of operations for cutting AWS spend — rightsizing, storage tiers, data transfer, and commitments — without degrading latency or reliability.

How to Reduce Your AWS Bill Without Sacrificing Performance

Most AWS cost advice starts in the wrong place. It tells you to buy Reserved Instances, which locks in whatever you are currently over-provisioning. The order matters: measure, remove, rightsize, tier, then commit. Commit last, because a commitment on wasteful usage just makes the waste cheaper per unit, not smaller.

This is the sequence we run when a client hands us an AWS account and a bill they cannot explain.

Where does the money actually go?

Open Cost Explorer and group by service, then by usage type, for the last 90 days. Almost every SMB bill we see concentrates in four places:

  • EC2 / ECS / EKS compute — usually the largest line, and usually over-provisioned because instance sizes were chosen during a load test that never happened.
  • RDS — often a Multi-AZ instance sized for a peak that occurs twice a year, plus snapshots nobody expires.
  • S3 and EBS storage — cheap per GB, expensive at rest for years, especially unattached EBS volumes and old snapshots.
  • Data transfer — NAT Gateway processing charges and cross-AZ traffic are the two lines most teams have never looked at.

Turn on Cost Allocation Tags before you change anything. Without Environment, Service, and Owner tags you are optimizing blind, and you cannot prove afterwards that the savings came from your change and not from a quiet month.

What can you delete outright?

Deletion is the only optimization with zero performance risk. Before touching instance sizes, sweep for resources nothing is using:

  • Unattached EBS volumes and snapshots older than your actual retention policy.
  • Idle Elastic IPs — an allocated but unassociated IPv4 address bills hourly, and since 2024 so does an in-use one.
  • Load balancers with no healthy targets, left behind by a deleted service.
  • Old RDS manual snapshots and automated backups beyond the retention you actually need for recovery.
  • Non-production environments running 24/7. A dev and staging fleet that sleeps nights and weekends runs roughly 25% of the hours, which is a ~75% cut on those environments with no production impact at all.

This pass alone typically removes 10–20% of a neglected bill and costs you nothing in latency.

How do you rightsize without risking latency?

Rightsizing is where teams get nervous, so anchor it in data rather than instinct. Use CloudWatch metrics over a full business cycle — at least four weeks, so you capture month-end batch jobs — and look at p95, not average. Average CPU hides the spike that matters.

A workable rule: if p95 CPU is under 30% and p95 memory is under 50% across four weeks, drop one instance size and watch p95 latency for a week. One size at a time. Two sizes at once means you cannot attribute a regression.

Two structural wins usually beat any amount of instance tuning:

  • Move to Graviton. ARM-based m7g/r7g/c7g instances and Graviton RDS run roughly 20% cheaper than the equivalent x86 size at comparable or better performance for most JVM, Go, Node, and Python workloads. The migration cost is a rebuild of your container images for arm64, which is usually a one-line change in a multi-arch build.
  • Autoscale on the right signal. Scaling on CPU when your bottleneck is queue depth or request concurrency means you scale late and over-provision to compensate. Scale on the metric that actually correlates with user-visible latency.

Spot Instances belong on stateless, interruption-tolerant work — batch jobs, CI runners, async workers, and stateless web tiers behind a load balancer. They can cut that compute by 60–90%. They do not belong under a stateful primary database or anything with a long, non-resumable startup.

Which storage should move tiers?

Storage tiering is the highest-ratio saving with the least performance exposure, provided you match the tier to the access pattern:

  • S3 Intelligent-Tiering for buckets with unknown or shifting access patterns. It moves objects between frequent and infrequent tiers automatically for a small monitoring fee per object, which is why it is a poor fit for buckets of millions of tiny objects.
  • S3 Glacier Instant Retrieval for archives you must be able to read immediately but rarely do. Glacier Deep Archive only where a multi-hour restore is genuinely acceptable — audit logs, compliance copies.
  • gp3 instead of gp2 for EBS. gp3 is roughly 20% cheaper per GB and lets you provision IOPS and throughput independently of volume size, so you stop buying a 1 TB volume just to get the IOPS.

Add S3 Lifecycle rules so this keeps working without anyone remembering to run it, and set an expiration on incomplete multipart uploads — a common source of storage nobody can see in the console.

What about the data transfer line?

This is the line item most teams discover late.

  • NAT Gateway charges both an hourly rate per gateway and a per-GB processing fee. If your private subnets are pulling container images or writing to S3 through NAT, you are paying processing fees for traffic that never needed to leave AWS. VPC Gateway Endpoints for S3 and DynamoDB are free and remove that traffic from NAT entirely. Interface endpoints for other services cost less than NAT processing at volume.
  • Cross-AZ traffic bills in both directions. Chatty microservices spread across three AZs for redundancy can generate a surprising bill talking to each other. Keep request-path chatter zone-local where your availability target allows it.
  • CloudFront in front of S3 or your ALB is usually cheaper per GB egressed to the internet than origin egress, and it lowers origin load at the same time. That is one of the rare changes that cuts cost and improves latency together.

When should you commit?

Only after the four steps above have settled — otherwise you are locking in waste for one to three years.

Savings Plans (Compute Savings Plans in particular) are more flexible than Reserved Instances: they apply across instance families, sizes, regions, and to Fargate and Lambda, in exchange for a slightly lower discount than a standardized RI. For most SMBs the flexibility is worth more than the extra few points.

Commit to your stable floor, not your peak. Look at the last 90 days of post-optimization spend, take the level your usage never drops below, and commit to roughly 70% of it on a one-year term. Let variable load ride on-demand or Spot. A three-year commitment on infrastructure you might re-architect next quarter is a bet, not a saving.

What to measure so it does not creep back

Cost optimization that is not monitored regresses within two quarters. Three controls hold the line:

  • AWS Budgets with alerts on both absolute spend and anomaly detection, routed to a channel a human reads.
  • Cost Anomaly Detection per service, which catches the runaway job faster than a monthly review.
  • A monthly 30-minute review of cost per tagged service against a business metric — cost per order, per tenant, per active user. Absolute spend rising while cost per unit falls is a company growing, not a problem.

Work with us

We take on AWS cost and infrastructure work as fixed-scope engagements: a review of your account against the sequence above, the Terraform to implement what we agree on, and the code in your repo and your cloud account at handoff. If you want the bill explained before you commit to changing anything, get in touch.

Need this built? Our team does fixed-scope devops & cloud — scoped, priced and delivered in weeks.