cloud icon

The 8 AWS Resources That Silently Drain Your Budget

By Jose Marin, founder of Cirrondly, March 2026

TL;DR: The 8 AWS resources that most commonly waste money in startup accounts are: unused Elastic IPs ($3.60/mo each), idle Application Load Balancers ($18/mo each), CloudWatch Logs with no retention policy ($0.03/GB/mo), old RDS snapshots ($0.095/GB/mo), overprovisioned DynamoDB tables (50-80% overcharge), unattached EBS volumes ($0.10/GB/mo), S3 buckets without lifecycle rules (up to 80% overspend), and idle ElastiCache clusters ($20-300/mo). Most startups have 4-5 of these, totaling $200-400/month in silent waste. Cirrondly scans all 8 automatically in under 60 seconds.

You didn't get a $400 AWS bill because you scaled too fast. You got it because something you forgot about kept running.

This is the most common pattern I see with startups on AWS: you spin up a resource during development, move on to the next thing, and three months later it's still there quietly billing you. No alerts. No warnings. Just a line item buried in Cost Explorer that you'll notice too late.

After building Cirrondly and scanning hundreds of AWS accounts, these are the 8 resources I see wasting money in almost every startup account.


1. Elastic IPs sitting unattached

What happens: You allocate an Elastic IP for an EC2 instance. You terminate the instance. The IP stays.

What it costs: $3.60/month per unused IP. Sounds small, until you have 5 of them across regions you forgot about.

Why it's sneaky: AWS charges you for not using an Elastic IP. While it's attached to a running instance, it's free. The moment you detach it or stop the instance, the meter starts. Most people assume "I deleted the server, everything is cleaned up." It's not.

How to check: Go to EC2 → Elastic IPs → look for any IP without an associated instance.


2. Idle Application Load Balancers

What happens: You set up an ALB for a project. The project gets shelved. The ALB stays up, processing zero requests.

What it costs: Around $18/month minimum, even with zero traffic. That's the base hourly charge alone.

Why it's sneaky: ALBs don't auto-delete. They don't warn you. And if you're running multiple environments (staging, dev, feature branches), you might have 3-4 idle ALBs you've completely forgotten about.

How to check: Go to EC2 → Load Balancers → check the "Request Count" metric in CloudWatch. If it's been zero for weeks, you're paying for nothing.


3. CloudWatch Logs with no retention policy

What happens: Every Lambda function, every ECS task, every API Gateway, they all dump logs into CloudWatch. By default, logs are kept forever.

What it costs: $0.03 per GB stored per month. Doesn't sound like much, but a busy Lambda can generate gigabytes of logs per month. After a year, you're storing hundreds of GBs of logs you'll never read.

Why it's sneaky: It grows so slowly that you never notice. Then one day you look at your CloudWatch bill and it's $50/month just for log storage. For logs from a service you decommissioned 6 months ago.

How to check: Go to CloudWatch → Log groups → sort by "Stored Bytes." Set a retention policy (7, 14, or 30 days is enough for most use cases).


4. Old RDS snapshots piling up

What happens: You create manual RDS snapshots before big changes. Good practice. But you never delete them.

What it costs: $0.095 per GB per month. A 100GB database snapshot sitting around for a year costs ~$114 for absolutely no reason.

Why it's sneaky: Automated snapshots get cleaned up by AWS based on your retention window. Manual snapshots don't. They sit there forever until you explicitly delete them. And if you took snapshots of a database you already deleted, there's zero reason to keep them.

How to check: Go to RDS → Snapshots → filter by "Manual." Sort by date. Anything older than 30 days probably needs to go.


5. Overprovisioned DynamoDB tables

What happens: You set up a DynamoDB table with provisioned capacity for a launch. The launch goes fine. The traffic stabilizes at 10% of what you provisioned for. The table keeps billing for the full capacity.

What it costs: 50-80% more than you need to pay. A table provisioned for 1,000 WCU when you're using 100 WCU is burning money every hour.

Why it's sneaky: If you're on provisioned mode and didn't set up auto-scaling (or set it up with a minimum that's too high), you're paying for capacity you'll never use. Switching to on-demand mode alone can save you 60%+ if your traffic is bursty.

How to check: Go to DynamoDB → Tables → Metrics tab. Compare your provisioned capacity vs. consumed capacity. If consumed is consistently below 30% of provisioned, you're overpaying.


6. Unattached EBS volumes

What happens: You terminate an EC2 instance but the EBS volume was set to "persist after termination." The volume survives. You now have a disk floating in your account, attached to nothing.

What it costs: $0.10 per GB per month for gp3 volumes. A 500GB volume you forgot about costs $50/month.

Why it's sneaky: This is the most common ghost resource in AWS. Volumes don't show up in the EC2 dashboard unless you specifically look at the Volumes section. They just sit there, billing quietly.

How to check: Go to EC2 → Volumes → filter by "State: available." "Available" means unattached. If you don't recognize it, snapshot it (just in case) and delete it.


7. S3 buckets with no lifecycle policy

What happens: You dump data into S3. Logs, backups, uploads, ML training data. You never set a lifecycle policy. Everything stays in S3 Standard forever.

What it costs: S3 Standard is $0.023/GB/month. Move old data to Glacier and that drops to $0.004/GB/month, that's an 80% reduction. For a bucket with 1TB of data you haven't touched in 6 months, that's ~$19/month you're wasting.

Why it's sneaky: S3 feels cheap. And it is per GB. But data accumulates fast, and without a lifecycle policy, nothing ever moves to a cheaper tier or gets deleted. Multiply this by 10 buckets and suddenly it's your second-biggest line item.

How to check: Go to S3 → pick a bucket → Management → Lifecycle rules. If it says "No lifecycle rules," you should fix that.


8. Idle ElastiCache clusters

What happens: You set up a Redis or Memcached cluster for caching. Your app evolves, the caching layer becomes less critical, but the cluster stays running.

What it costs: $20 to $300+ per month depending on instance type. A cache.r6g.large runs about $150/month. That's a meaningful chunk of budget for a cache nobody's hitting.

Why it's sneaky: ElastiCache doesn't have a simple "requests per second" metric that screams "I'm idle." You have to dig into CloudWatch metrics like CurrConnections and GetHits to figure out if anyone is actually using it.

How to check: Go to ElastiCache → Clusters → check CloudWatch metrics for CurrConnections. If it's near zero consistently, you're paying for an unused cache.


The real problem isn't the money. It's the pattern!

Each of these resources costs $5, $18, $50 alone. But the pattern is always the same: you have 4 or 5 of them, across 2 or 3 regions, and suddenly you're burning $200-400/month on resources that do nothing.

The worst part: AWS won't tell you. Cost Explorer shows you totals by service, but it won't say "hey, this specific Elastic IP has been unattached for 90 days." Trusted Advisor catches some of it, but only on Business or Enterprise support plans that cost $100+/month.

That's the gap we built Cirrondly to fill. It's an AI agent that connects to your AWS account (read-only, via IAM role, no credentials stored), scans for exactly these 8 types of waste, and tells you what to fix in plain language. You approve, it executes. No dashboards to interpret, no reports to download.

If you want the manual cleanup version of this article, use How to Reduce Your AWS Bill in 30 Minutes. It walks through the console steps for fixing the highest-impact waste first.

If you're running a startup on AWS, you probably have at least 3 of these right now.


Check your AWS account for waste right now - two ways:

Free CSV diagnosis (10 seconds, no signup): Export your Cost Explorer CSV and upload it. You'll see exactly which services are costing you more than they should. Try the free diagnosis →

Full agent (connects to your AWS account): Cirrondly scans your actual resources, detects idle instances, unattached volumes, and overprovisioned databases - then fixes them with your approval. Start saving with Cirrondly →


Jose Marin is the founder of Cirrondly and a full-stack engineer with 9 years of experience. Previously CTO. Based in Lyon, France. He builds tools that help startups use AWS without billing anxiety.

Keep reading

Related posts

View all posts