We audited 10 AWS accounts. Here's where the money was wasted.
Most engineering teams have no idea where their AWS bill actually goes. Not in a hand-wavy sense — in a very literal one. They know the total. They might know which service tops the chart. But ask them why their bill jumped 30% in two months and you'll get silence, or a guess about "traffic growth."
Over the past year, we've audited 10 AWS accounts across startups and mid-size engineering teams. Companies running anywhere from $3,000 to $40,000/month in AWS spend. The pattern is remarkably consistent: between 25% and 40% of the bill is waste. Not optimization opportunities. Waste. Resources doing nothing, services over-provisioned by 4x, architectural decisions nobody revisited after week one.
Here are the four categories that showed up in nearly every audit.
1. NAT gateway data processing: the silent killer
This one surprises people every time. NAT gateways charge $0.045 per GB of data processed. That doesn't sound like much until you realize every byte of outbound traffic from your private subnets flows through it — container image pulls from ECR, API calls to third-party services, log shipping, S3 uploads, all of it.
In one account, a team was pulling 2 TB/month through their NAT gateway. That's $90/month just in data processing fees, on top of the $32/month hourly charge per gateway. They had NAT gateways in three AZs, so triple it. Nearly $370/month in NAT costs alone — for a team running six microservices.
The fix is straightforward: VPC endpoints. An interface endpoint for ECR, a gateway endpoint for S3 (which is free), and endpoints for CloudWatch and STS. This cuts NAT traffic by 60-80% for most workloads. We've seen teams save $200-500/month with 15 minutes of Terraform work.
We won't detail the full endpoint strategy here, but the short version: if you're running EKS or ECS in private subnets and you don't have VPC endpoints configured, you're almost certainly overpaying on NAT.
2. Over-provisioned RDS instances
This is the most common one, and the most expensive. Teams pick a database instance size during the initial setup — usually because someone Googled "recommended RDS instance for production" — and never revisit it.
In eight out of ten audits, the primary RDS instance was provisioned at 2x to 4x the required capacity. The worst case: a db.r5.xlarge (4 vCPUs, 32 GB RAM) running a PostgreSQL database that averaged 50 queries per second with peak CPU at 12%. That instance costs roughly $350/month. A db.t4g.medium would have handled the load comfortably at $55/month.
The same pattern applies to read replicas that were set up "just in case" and Multi-AZ deployments on development databases that nobody ever fails over. One team had Multi-AZ enabled on their dev database — literally doubling the cost for a database that gets wiped every two weeks.
CloudWatch metrics tell you exactly what you need. Check CPUUtilization, DatabaseConnections, and FreeableMemory over a 30-day window. If your peak CPU never crosses 30% and you have 20+ GB of free memory, you're over-provisioned. The specific right-sizing methodology depends on the workload, but the data is already there — most teams just never look at it.
3. Forgotten resources: the graveyard in every account
Every AWS account we've audited has a graveyard. Resources that were created for a project, a test, a proof of concept — and then abandoned. Nobody deleted them because nobody remembered they existed, or because deleting things in production accounts feels risky.
The usual suspects:
- EBS snapshots — automated backups with no lifecycle policy. We found one account with 4 TB of EBS snapshots dating back 18 months. At $0.05/GB, that's $200/month for backups of volumes that no longer exist.
- Idle EKS clusters — this one is personal. We shut down a dev EKS cluster in our own account that had been sitting idle for months. Control plane alone: $73/month. No workloads. No traffic. Just $73/month for a Kubernetes API endpoint responding to nobody. Multiply that across accounts with "staging-old," "test-cluster-2," and "eks-demo," and you see the problem.
- Elastic IPs — AWS charges $0.005/hour ($3.65/month) for each Elastic IP that isn't attached to a running instance. Small individually, but we routinely find 5-10 of them per account.
- Old load balancers — ALBs that were provisioned for services that no longer exist. Minimum $16/month each, plus LCU charges.
The pattern is always the same: creation is easy, cleanup never happens. We have a systematic way of finding these, but the core problem isn't technical — it's process. If your team doesn't have a regular cadence for reviewing running resources, the graveyard will keep growing.
4. Load balancer sprawl
This is the architectural mistake that costs the most in the long run. Team deploys microservice A, creates an ALB. Team deploys microservice B, creates another ALB. By the time you have eight services, you have eight ALBs — each costing a minimum of $16/month in fixed charges plus per-LCU usage.
That's $128/month minimum for load balancing alone, before a single request is served. We've seen accounts spending $300-500/month on ALBs for services that could all route through a single shared ingress.
The alternative: one load balancer — an NLB or ALB — fronting a shared ingress controller like Kong or nginx. Host-based and path-based routing handle the distribution. One load balancer, one DNS entry, one TLS certificate. The teams that adopt this pattern early save thousands over the life of a project. The teams that don't end up with a spaghetti of load balancers, target groups, and security group rules that nobody wants to untangle.
We won't lay out the full migration path here — it depends on your service mesh, your TLS strategy, and whether you're running Kubernetes or ECS — but if you're currently running more than two ALBs for internal services, it's worth a conversation.
What this adds up to
Across the 10 accounts we audited, the average annual waste was $14,000. The highest was over $40,000. These aren't accounts with runaway GPU instances or massive data pipelines — they're standard web application stacks. APIs, databases, a few background workers. The kind of infrastructure most startups and growth-stage companies run.
The frustrating part is that most of this waste is fixable in a week. VPC endpoints, RDS right-sizing, resource cleanup, and load balancer consolidation. No re-architecture required. No downtime. Just someone taking the time to actually look.
We run AWS cost audits as a service. If your monthly bill feels higher than it should be — or you just don't know where the money goes — get in touch. We'll tell you exactly what's costing you and what to do about it.
Vishwaraja Pathi
Cloud & DevOps specialist with 13+ years of experience. Founder of Adiyogi Technologies. Previously at Roku, Rocket Lawyer, and BetterPlace.