Most companies running on AWS are overpaying. Not by a rounding error — industry analyses of cloud spending consistently put wasted spend somewhere in the 30% range across the market as a whole.
The reason usually isn’t incompetence. It’s ownership. Engineering optimises for shipping features and keeping things up. Finance sees a single monthly invoice with no visibility into what drives it. In between, nobody is specifically accountable for the number going up.
The good news is that most cloud waste comes from a small, predictable set of causes. This article walks through the six most common ones we see, what each typically costs, and roughly what fixing it is worth. It’s written for founders and CTOs — you shouldn’t need to be a DevOps engineer to follow it.
One caveat before we start: every percentage below is a typical range, not a guarantee. Real savings depend entirely on your architecture and workload. Treat these as places to look, not promises.
1. Servers Running at 12% CPU
This is the single most common source of waste, and it has an entirely human explanation.
Early in a project, someone has to pick an instance size. There’s no production traffic data yet, the cost of being under-provisioned (an outage) feels far worse than the cost of being over-provisioned (a slightly bigger bill), so they round up “to be safe.” That’s a reasonable decision at the time.
The problem is that nobody ever revisits it. Two years later, that instance is still running, still oversized, and still billing every hour.
How to check
In CloudWatch, look at average CPU utilisation across 30 days for your EC2 instances and RDS databases. Sustained utilisation below 20% is a strong signal you’re paying for roughly four times the machine you need. AWS Compute Optimizer will also generate right-sizing recommendations automatically, and it’s free.
A word of caution: CPU isn’t the whole picture. Some workloads are memory-bound or I/O-bound and will show low CPU while genuinely needing the instance. Check memory and network metrics before downsizing anything, and change one instance at a time.
Typical saving: 30–50% of EC2 spend.
2. Paying On-Demand Prices for Predictable Workloads
On-demand pricing exists so you can spin up capacity instantly without commitment. You pay a premium for that flexibility, and for genuinely unpredictable workloads, it’s worth it.
But your production database isn’t unpredictable. Neither is your main application server. These run continuously, every hour of every day, and they will still be running next year. Paying a flexibility premium for something completely predictable is pure waste.
AWS offers two main alternatives for committed usage:
- Savings Plans — you commit to a consistent dollar amount of compute usage per hour for one or three years, in exchange for significantly lower rates. Compute Savings Plans are the flexible option, applying across instance families, regions, and even Fargate and Lambda.
- Reserved Instances — a more specific commitment tied to instance attributes, still widely used for RDS and other services.
AWS advertises discounts of up to roughly 72% for the deepest three-year, all-upfront commitments. Most companies won’t hit that ceiling, but even a one-year, no-upfront Compute Savings Plan typically delivers meaningful double-digit savings with very little downside.
There’s also Spot Instances — spare AWS capacity at discounts that can reach around 90%, with the catch that AWS can reclaim the capacity with two minutes’ notice. Never use Spot for your primary database. It’s excellent for batch processing, CI/CD runners, data pipelines, and any fault-tolerant workload that can be interrupted and resumed.
Typical saving: 20–40% of compute spend.
3. Development Environments Running All Night
Your team works something like 45 to 50 hours a week. Your development and staging environments bill for all 168.
That means for roughly 70% of every week, you’re paying full price for environments with nobody logged into them. Unlike production, these environments have no uptime requirement whatsoever. If staging is down at 3am on a Sunday, nothing happens.
How to fix it
A scheduler that stops non-production instances outside working hours is genuinely a one-afternoon piece of work. AWS Instance Scheduler is a supported solution for this, but a simple Lambda function on an EventBridge schedule works just as well — stop instances at 8pm, start them at 8am, skip weekends.
The main objection is usually “but what if someone needs it at night?” In practice, giving the team a self-service way to start an environment on demand solves this completely, and the exceptions are rare enough that the savings hold.
Typical saving: 65–70% of non-production spend.
4. Storage for Servers That No Longer Exist
This is the most frustrating category, because you get absolutely nothing in return for the money.
When you terminate an EC2 instance, its attached EBS volume doesn’t always go with it — depending on how it was configured, the volume can survive, unattached to anything, billing every month indefinitely. The same happens with:
- Orphaned EBS snapshots. Teams take snapshots before risky changes and never clean them up. Years of them accumulate.
- Unattached Elastic IPs. AWS charges for Elastic IP addresses that aren’t associated with a running instance.
- Idle load balancers. A load balancer left behind after a service was decommissioned bills an hourly rate for doing nothing.
- Empty or unused NAT Gateways. These carry an hourly charge regardless of whether traffic flows through them.
None of this is serving a user. None of it is supporting a workload. It’s abandoned infrastructure that nobody remembered to delete.
AWS Trusted Advisor flags several of these categories directly. A quarterly cleanup review is usually enough to keep it under control. For most mid-sized companies this recovers a few hundred dollars a month; for larger or older accounts, it can be dramatically more.
Typical saving: highly variable, but always pure profit — nothing is lost by removing it.
5. Data Transfer Costs You Can’t See
This is the sneakiest category on the list, because the charges don’t appear next to the resources causing them.
Two things dominate here:
NAT Gateway processing charges
NAT Gateways charge both an hourly rate and a per-gigabyte data processing fee for everything passing through them. If your services in private subnets are pulling large amounts of data from the internet — container images on every deployment, package downloads, external API calls — that processing fee accumulates quietly.
The common fix is VPC Endpoints. Traffic to services like S3 and DynamoDB can route through an endpoint instead of the NAT Gateway, avoiding the processing charge entirely for that traffic.
Cross-availability-zone traffic
AWS charges for data moving between availability zones inside the same region — in both directions. This is the one that catches teams out.
If you’ve split a chatty set of microservices across multiple AZs for resilience, every internal call between them may now be a billable cross-AZ transfer. You did the architecturally responsible thing and got a surprise line item for it.
The answer isn’t to abandon multi-AZ redundancy — that’s there for good reason. It’s to be deliberate about which services genuinely need to talk across zones, and to keep high-volume chatty communication zone-local where availability requirements allow.
Typical impact: often 5–15% of the total bill, and almost always underestimated.
6. Logs and Backups You Will Never Read
By default, CloudWatch log groups retain data indefinitely. Not for 30 days, not for a year — forever, unless someone explicitly sets a retention policy.
That means many companies are paying premium storage rates to keep application logs from years ago that no human will ever open. The same applies to S3 buckets without lifecycle rules, where data that’s been untouched for years still sits in the most expensive storage class.
The two fixes
- Set CloudWatch retention policies. Decide how long logs are actually useful — 30, 60, or 90 days for most application logs — and configure it. Anything you need for compliance can be exported to cheaper storage first.
- Use S3 lifecycle policies and storage classes. S3 offers a range of tiers, from Standard down to Glacier Deep Archive, at dramatically different price points. S3 Intelligent-Tiering will move objects between access tiers automatically based on usage, which is a reasonable default when access patterns are unpredictable.
Both are configured once and keep saving money indefinitely, with no ongoing effort.
Typical saving: modest as a percentage, but permanent and effortless.
Where to Actually Start
If you do nothing else, do this: open AWS Cost Explorer, group your spend by service, and look at your top three lines.
Cloud bills follow a Pareto pattern almost universally. A small number of services account for the overwhelming majority of the cost. Optimising a service that represents 2% of your bill is a poor use of engineering time, no matter how inefficient it is. Start where the money actually is.
Three practices matter more than any individual optimisation:
- Tag everything. Without resource tags for environment, team, and project, you can’t attribute cost to anything. Cost allocation tags turn an opaque invoice into an actionable breakdown.
- Set budget alerts. AWS Budgets can notify you when spend crosses a threshold or is forecast to. Finding out about a cost spike on the 3rd rather than the 30th is the difference between a small problem and a large one.
- Give the bill an owner. Not a committee — a named person who reviews it monthly and is expected to explain changes. This single organisational change tends to outperform any technical fix.
Cloud spend isn’t a technical problem. It’s an ownership problem.
A Note on Over-Optimising
It’s worth saying the obvious counterpoint: cost optimisation has diminishing returns, and engineering time isn’t free.
If your monthly AWS bill is $800, spending three engineer-weeks to save 20% is a bad trade. If it’s $80,000, the same effort is obviously worth it. And some spending that looks wasteful is actually buying you something real — multi-AZ redundancy costs more and is usually correct; over-provisioned capacity ahead of a known traffic event is prudent, not careless.
The goal isn’t the lowest possible bill. It’s a bill where every line item is a decision someone made on purpose.
How We Approach This at Onclick Innovations
We build and maintain cloud infrastructure for clients across fintech, healthcare, e-commerce and SaaS, and cost efficiency is something we treat as an architectural concern from the start rather than a cleanup exercise later. Right-sizing, environment scheduling, storage lifecycle rules and sensible tagging are far cheaper to build in at the beginning than to retrofit onto a system that’s already running in production.
Frequently Asked Questions
How much are most companies overspending on AWS?
Industry analyses of cloud spending consistently estimate that roughly 30% of cloud spend is wasted across the market. The figure for any individual company varies widely depending on architecture, workload predictability, and whether anyone actively reviews the bill.
What’s the fastest way to reduce an AWS bill?
Usually two things: right-sizing over-provisioned instances, and scheduling non-production environments to shut down outside working hours. Both are relatively quick to implement and carry low risk compared to architectural changes.
What’s the difference between Savings Plans and Reserved Instances?
Savings Plans commit you to a consistent hourly dollar amount of compute usage and apply flexibly across instance families, regions, and services including Fargate and Lambda. Reserved Instances are tied more specifically to instance attributes. Savings Plans are generally the more flexible option for EC2 compute; Reserved Instances remain common for services like RDS.
Are Spot Instances safe to use?
For the right workloads, yes. AWS can reclaim Spot capacity with two minutes’ notice, so they should never run your primary database or anything that can’t tolerate interruption. They’re well suited to batch jobs, CI/CD runners, data processing, and other fault-tolerant workloads.
Why is AWS data transfer so expensive?
Data transfer charges come from several sources, most commonly NAT Gateway per-gigabyte processing fees and cross-availability-zone traffic within a region. They’re easy to miss because the charges don’t appear alongside the resources generating them. VPC Endpoints and keeping high-volume internal traffic zone-local are the usual mitigations.
What tools does AWS provide for cost management?
Cost Explorer for analysing spend, AWS Budgets for alerts and forecasting, Compute Optimizer for right-sizing recommendations, and Trusted Advisor for flagging idle and unused resources. All are available within the AWS console.
