FinOps
7 common mistakes that lead to overspending on AWS
Idle resources, oversized EC2, gp2 defaults, NAT Gateway data charges and the wrong commitments: 7 AWS billing mistakes that inflate your bill, and the fixes.
Most AWS overspend isn’t one bad decision. It’s a stack of small defaults nobody went back to: a NAT Gateway left over from a test, a gp2 volume created years ago, a Savings Plan sized for last year’s fleet. None of them look alarming in the console. All of them show up on the invoice.
We call these patterns FinOps smells. CloudFix has analyzed $2B+ in AWS spend for 500+ companies, and the same seven keep turning up. This is the 2026 update of a list we first published in 2023. Prices are AWS on-demand list prices in us-east-1.
The seven mistakes at a glance
| Mistake | Where it shows on the bill | How CloudFix handles it |
|---|---|---|
| 1. Leaving idle resources running | EC2, NAT Gateway, EBS and public IPv4 charges | Automated fixers stop or remove them after you approve |
| 2. Running EC2 like a data center | Flat EC2 spend, oversized instances, Extended Support fees | Rightsizing, Auto Scaling group resizing, end-of-life version flags |
| 3. Accepting default storage settings | gp2 volumes, S3 Standard, old snapshots, log storage | gp2 to gp3, S3 Intelligent-Tiering, snapshot archiving, log retention |
| 4. Ignoring data transfer | NAT Gateway data processing, cross-AZ traffic, egress | Gateway endpoints, CloudFront compression |
| 5. Getting commitments wrong | Full on-demand rates, or unused RIs and Savings Plans | RightSpend Commitment-Free Discounts: 20-55% off on-demand EC2 |
| 6. One giant account, no tags | Spend nobody owns | Findings tied to a specific resource in a specific account |
| 7. Finding out from the invoice | Surprises, and recommendations nobody acts on | 110+ finders; approved fixes run through AWS Systems Manager |
1. Leaving idle resources running
Forgotten resources are behind many surprise AWS bills. Someone spins them up for a test, a migration or a demo. The project ends. The resources don’t.
AWS can’t tell whether you left something on deliberately, so it bills for every hour it exists. Here’s what common leftovers cost:
| Idle resource | What it costs doing nothing |
|---|---|
| NAT Gateway | $0.045 per hour, about $33 a month, before any data |
| Application Load Balancer | $0.0225 per hour, about $16 a month, plus capacity units |
| Public IPv4 address | $0.005 per hour, about $3.65 a month, attached or not |
| Unattached gp2 EBS volume | $0.10 per GB-month, so $50 a month for 500 GB |
| Stopped EC2 instance | No compute charge, but its EBS volumes keep billing |
Small ones add up across dozens of accounts. Big ones hurt fast: the largest GPU instances list at tens of dollars an hour, so one left on over a long weekend is a four-figure line item. Idle SageMaker notebooks are a repeat offender.
The fix: tag every resource with an owner and an expiry date, shut down non-production environments outside working hours, and review what’s running every week.
That works until the week nobody does it. CloudFix finders look for exactly these leftovers: idle EC2 instances, idle NAT Gateways, idle load balancers, unused Elastic IPs, unattached EBS volumes and idle SageMaker notebooks. Each one has an automated fixer that stops or removes the resource once you approve it.
2. Running EC2 like a data center
Many teams move to AWS and keep their on-prem habits: buy for peak, leave it running, never look again. As AWS Made Easy guest Keith Hodo put it, treating AWS as a colocation facility gets you “your mess, for more [money].”
It shows up three ways:
- Oversized. Instances sized for launch-day load and never revisited. Low CPU and memory utilization, week after week.
- Fixed. The same compute footprint every hour of every week, while real demand rises and falls. Dev and test fleets run all night and all weekend.
- Old. Previous-generation instance families deliver less work per dollar than current ones, and many workloads run cheaper again on Graviton. Old software versions cost more too. RDS for MySQL 8.0 left standard support on July 31, 2026, and RDS moves databases on an unsupported major version into paid Extended Support by default, billed per vCPU-hour on top of the instance price. On EKS, a cluster on a Kubernetes version in extended support pays $0.60 per cluster-hour instead of $0.10.
The fix: rightsize from real utilization data, put stateless workloads in Auto Scaling groups, schedule non-production, move to current-generation instance types, and upgrade before a version leaves standard support.
CloudFix finds oversized EC2 instances, resizes instances in Auto Scaling groups, turns on AWS Compute Optimizer, moves Lambda functions to Graviton, and flags databases and clusters heading into Extended Support. Some are automated fixers; others, including major-version upgrades, are guided fixes you apply yourself.
3. Accepting default storage settings
Storage looks cheap per GB, so nobody checks it.
- gp2 volumes. Older templates, AMIs and modules still create gp2. gp3 lists at $0.08 per GB-month against $0.10 for gp2, which is 20% less, and includes 3,000 IOPS and 125 MB/s at any size. The change is made in place with Elastic Volumes. Our gp2 vs gp3 comparison walks through it.
- S3 Standard for everything. At $0.023 per GB-month, logs and backups nobody has opened in a year cost the same as your busiest data. S3 Intelligent-Tiering moves objects to cheaper tiers after 30 and 90 days without access, with no retrieval fees. Objects under 128 KB aren’t tiered, and there’s a small per-object monitoring fee.
- The opposite mistake. Lifecycle rules that push data to Glacier too early. Glacier storage classes have retrieval fees and minimum storage durations, so data you still need gets expensive to read back.
- Snapshots and logs that never expire. EBS snapshots pile up for years. New CloudWatch log groups keep data forever unless you set a retention period.
CloudFix has automated fixers that retype gp2 volumes to gp3, enable S3 Intelligent-Tiering, archive old EBS snapshots and set CloudWatch log retention.
4. Ignoring data transfer charges
Data transfer is the part of the bill most teams can’t explain. It’s spread across services and grows with traffic, not with anything you provisioned.
The expensive patterns:
- S3 traffic through a NAT Gateway. A NAT Gateway charges $0.045 for every GB it processes. If instances in private subnets reach S3 or DynamoDB through it, you pay that on every GB: about $460 a month for every 10 TB. A gateway VPC endpoint for S3 or DynamoDB carries the same traffic at no charge.
- Cross-AZ chatter. Traffic between Availability Zones costs $0.01 per GB in each direction. Chatty microservices, replicas and log shipping spread across zones pay it all day.
- Internet egress. Data out to the internet lists at $0.09 per GB for the first 10 TB a month, after the free allowance. Uncompressed responses pay for bytes you didn’t need to send.
The fix: add gateway endpoints for S3 and DynamoDB in every VPC, keep chatty services in one zone where resilience allows, and serve static content through CloudFront with compression on.
CloudFix moves S3 and DynamoDB traffic from NAT Gateways to gateway endpoints and turns on CloudFront compression, both as automated fixers, and flags instances with unusually high network cost for review.
5. Getting commitments wrong, in either direction
Commitments are a big lever on EC2 cost, and teams get them wrong in two ways.
Too little. Steady production workloads run at on-demand rates for years because nobody wants to sign a commitment. That’s paying list price for a baseline that hasn’t moved.
Too much, or too rigid. Reserved Instances and Savings Plans can take up to 72% off on-demand, but only if you forecast one to three years of usage correctly. Teams buy for peak, then rightsize, move to Graviton or containerize. The commitment stays. The usage it covered doesn’t. A Savings Plan generally can’t be canceled once bought, and a Standard Reserved Instance is tied to one instance family.
Worse, rightsizing and commitments pull against each other. Every instance you shrink or remove leaves a slice of commitment with nothing to cover, so teams either stop optimizing or keep paying for commitments they no longer use.
RightSpend removes that conflict and works alongside CloudFix. Its Commitment-Free Discounts take 20-55% off on-demand EC2 with no 1- or 3-year lock-in. It doesn’t tie you to instance types or families: when CloudFix resizes or removes an instance, RightSpend drops that coverage. The fee is 25% of the net-new savings it generates, so you keep 75% and pay nothing on savings you already had. Get a range from the RightSpend calculator, or see how it compares in RightSpend vs ProsperOps.
6. Running one giant account with no tags
Most companies start on AWS with a single account. Past a certain size, that becomes a FinOps problem and a security problem.
One account is like dinner for 40 people with one bill. You know the total. You don’t know who ordered the lobster. Without account boundaries and consistent tags, nobody can say what’s driving cost, so nobody owns it. And one account where everyone has broad permissions is one big blast radius when something goes wrong.
The fix:
- Split workloads into accounts under AWS Organizations: by environment (dev, staging, production), business unit or application.
- Set a tagging policy with a required set of tags, such as owner, team, environment and cost center. Enforce it with tag policies.
- Activate those tags as cost allocation tags in the Billing console. Tags that aren’t activated don’t show up in Cost Explorer or your Cost and Usage Report.
- Go past showback. Spend reports get ignored; chargeback that changes incentives gets action.
CloudFix deploys its finders to the organizational units you choose, and every finding points at a specific resource in a specific account, so the team that owns it can act on it.
7. Finding out from the invoice
The most expensive mistake is having no early warning. Nothing in AWS caps your spend by default. If a job loops or a scaling policy misfires, you find out when finance forwards the bill.
The worst version is a leaked access key. Bots scan public repositories for AWS credentials and use them to launch compute, often in regions you never use.
The fix:
- Set AWS Budgets on actual and forecasted spend for every account, with alerts that go to the people who own it.
- Turn on AWS Cost Anomaly Detection. It’s free, and it flags unusual spend by service, account or tag.
- Replace long-lived access keys with IAM roles and IAM Identity Center, turn on secret scanning in your repositories, and block regions you don’t use with a service control policy.
Alerts still tell you after the money is spent. Recommendations aren’t savings either. Trusted Advisor, Cost Explorer and Compute Optimizer all produce lists, and someone still has to check each change, schedule it and make it. That’s why recommendations don’t equal savings. Behavior change only goes so far. Automation is what stops waste coming back.
CloudFix runs 110+ finders across 30+ AWS services and scans continuously as your accounts change. Each opportunity shows what it would save, and you approve the fixes you want. Approved fixes run as AWS Systems Manager Automation runbooks in your own account, under a dedicated CloudFix role, and every execution is logged. 53 finders have automated fixers; the rest are recommendations with steps you apply yourself. See the full finder/fixer catalog, or how CloudFix compares with Trusted Advisor.
What fixing these is worth
Together, these fixes typically save 15-60% on each AWS service CloudFix optimizes, which adds up to 20-35% off the total bill. The average is 23% off the total AWS bill. On a $1M annual bill, that’s $230,000.
If you’d rather start by hand, the AWS cost optimization checklist lists 30+ optimizations you can make this week.
Find out which of these seven are in your accounts. Connecting takes about 5 minutes, and your savings report is typically ready within 24 hours. Get your free AWS savings assessment.