The Real Cost of Abandoned AWS Resources (And How to Find Them)
Last month, I helped a mid-size SaaS company audit their AWS spend.
Last month, I helped a mid-size SaaS company audit their AWS spend. Their monthly bill was hovering around $47,000. Not outrageous for a team running production workloads across three regions. What was outrageous: roughly $11,200 of that — nearly a quarter — was going toward resources that nobody was using.
Unattached EBS volumes. Stopped EC2 instances with attached storage. Elastic IPs sitting there doing nothing except generating hourly charges. An RDS Multi-AZ instance that was spun up for a load test eight months ago and never terminated.
This isn't unusual. In fact, based on what we see across Pavora scans, most AWS accounts are carrying between 15% and 30% waste. The problem isn't that teams are reckless. It's that AWS makes it trivially easy to create resources and annoyingly hard to track whether they're still needed.
Where the Money Goes
Let me break down the usual suspects, because the distribution is remarkably consistent across organizations:
EBS Volumes (30-40% of waste)
When you terminate an EC2 instance, attached EBS volumes can persist depending on the DeleteOnTermination flag. The default for additional volumes (not the root) is false. So every time an engineer tears down a test instance but forgets to delete the extra volumes, you're paying for storage that serves no purpose.
At $0.08/GB/month for gp3 volumes, a single forgotten 500GB volume costs $40/month. That's nothing in isolation. But multiply it by 50 volumes across your organization, and you're looking at $24,000 per year in pure waste.
Stopped EC2 Instances (20-25% of waste) A stopped EC2 instance doesn't incur compute charges. People know this, so they stop instances instead of terminating them, thinking they're saving money. What they forget: the EBS volumes attached to stopped instances still incur charges. If those volumes are io2 or provisioned IOPS, the cost can be substantial.
We routinely find instances that have been stopped for 6+ months. At that point, the data on those volumes is almost certainly stale. But nobody wants to be the person who deletes them, because "what if we need it?"
Elastic IPs (5-10% of waste) AWS charges $0.005 per hour for each Elastic IP that's allocated but not associated with a running instance. That's $3.60/month per IP. Most accounts have between 5 and 20 unassociated EIPs. It's pocket change individually, but it adds up — and more importantly, it's a signal of poor hygiene that usually correlates with larger issues.
Old Snapshots (15-20% of waste) EBS snapshots are incremental, so people assume they're cheap. And they are — individually. But organizations that run daily snapshots without a lifecycle policy can accumulate thousands of snapshots over time. We've seen accounts with 10,000+ snapshots totaling several terabytes of storage. At $0.05/GB/month, that's not trivial.
NAT Gateways (10-15% of waste) A NAT Gateway costs $0.045/hour plus data processing charges, which works out to roughly $32/month even with zero traffic. If you've got NAT Gateways in VPCs that were set up for testing and never torn down, they're burning money silently.
The Security Angle Nobody Talks About
Here's the part that gets overlooked in most cost-optimization discussions: abandoned resources aren't just a financial problem. They're a security liability.
That stopped EC2 instance with a 500GB EBS volume? It probably has application data on it. Maybe credentials in a config file. Maybe a database dump from a migration. If an attacker gains access to your account, those volumes are trivially easy to attach to a new instance and read.
Those old EBS snapshots? They might contain full disk images from production servers. If they're not encrypted, anyone with access to your account can restore them and extract sensitive data.
The unattached Elastic IPs? If you release them back to AWS's pool, another customer might get assigned the same IP. If your DNS records still point to that IP, traffic intended for your service could end up at someone else's infrastructure. It's happened before — it's called a "dangling DNS" vulnerability.
What Good Hygiene Looks Like
After running hundreds of waste scans, here's the playbook that works:
-
Tag everything with an owner and an expiry date. Use a tag like
ttl: 2026-07-15and run a daily Lambda that terminates resources past their TTL. This single practice eliminates the majority of long-lived waste. -
Set EBS
DeleteOnTerminationtotruefor all non-persistent volumes. Update your launch templates and Terraform modules. This prevents the most common source of orphaned volumes. -
Implement snapshot lifecycle policies. AWS Data Lifecycle Manager (DLM) can automatically create and delete snapshots based on schedules you define. There's no reason to manage this manually.
-
Review stopped instances weekly. If an instance has been stopped for more than 14 days, create an AMI from it (if you need the data), then terminate it. AMIs are cheaper to store than running EBS volumes.
-
Audit NAT Gateways quarterly. Cross-reference them with your VPC architecture documentation. If a VPC doesn't have active workloads, delete the NAT Gateway.
Automating the Hunt
Manual audits are important, but they don't scale. You need automated scanning that runs continuously and flags new waste as it appears.
Pavora's waste detection module scans your entire AWS footprint and identifies abandoned, idle, and underutilized resources across EC2, EBS, RDS, ElastiCache, Elastic IPs, NAT Gateways, and more. Each finding includes an estimated monthly cost, so you can prioritize cleanup by financial impact.
We've seen teams recover between $5,000 and $50,000 per month after their first scan. The scan itself takes minutes and requires only read-only access to your account.
Your AWS bill doesn't have to be a mystery. Start scanning today.
Secure your AWS infrastructure
Pavora scans 204 AWS services for misconfigurations, vulnerabilities, and compliance gaps.