EBS Volumes: The Silent Budget Killer

Post Cover

EC2 and RDS get all the attention. But EBS — that boring storage layer underneath everything — might be silently costing you thousands.

Here's how to find and fix EBS waste.

The Hidden Cost of EBS

EBS costs come in three flavors:

1. Volume storage: Pay per GB provisioned per month 2. IOPS: Pay for provisioned IOPS (on io1/io2) 3. Snapshots: Pay per GB stored

Sounds simple. It's not.

Because you pay for provisioned storage, not used storage. A 1TB volume that's 10% full costs the same as a 1TB volume that's 99% full.

And those snapshots? They stick around forever unless you delete them.

The Five EBS Money Pits

1. Oversized Volumes

This is the most common waste.

"I might need more space later" → Provision 500GB Actual usage → 47GB

You're paying 10x what you need.

How to find them:
aws cloudwatch get-metric-statistics \
  --namespace AWS/EBS \
  --metric-name VolumeReadOps \
  --dimensions Name=VolumeId,Value=vol-xxx \
  --start-time 2024-01-01T00:00:00Z \
  --end-time 2024-01-31T23:59:59Z \
  --period 86400 \
  --statistics Sum

Low I/O + large size = probably oversized.

The fix: Resize volumes down. Yes, you can shrink EBS now (sort of). Create a smaller volume, copy data, swap.

2. Unattached Volumes

Instances get terminated. Volumes stick around.

"We might need that data" → Volume sits orphaned Months later → Nobody remembers what it was

How to find them:
aws ec2 describe-volumes \
  --filters Name=status,Values=available \
  --query 'Volumes[*].{ID:VolumeId,Size:Size,Created:CreateTime}'

"Available" means attached to nothing.

The fix: Review each one. If nobody knows what it is, snapshot it (just in case) and delete the volume.

3. Wrong Volume Types

Volume types have very different costs:

| Type | Cost/GB/month | Use Case | |------|---------------|----------| | gp3 | $0.08 | General purpose (most workloads) | | gp2 | $0.10 | Legacy general purpose | | io2 | $0.125+ | High IOPS requirements | | st1 | $0.045 | Throughput-optimized (big data) | | sc1 | $0.015 | Cold storage |

Running logs on gp2 when sc1 would work? That's 7x the cost.

How to find them:
aws ec2 describe-volumes \
  --query 'Volumes[*].{ID:VolumeId,Type:VolumeType,Size:Size,IOPS:Iops}'

Look for io1/io2 volumes with low IOPS utilization. Look for gp2 volumes (should mostly be gp3 by now).

The fix:
  • Migrate gp2 → gp3 (no downtime, usually cheaper)
  • Migrate io1/io2 → gp3 if IOPS requirements allow
  • Use st1/sc1 for archival and logs

4. Snapshot Sprawl

Snapshots are cheap. But they add up.

Every daily backup creates a snapshot. Over years, you accumulate thousands.

I've seen companies with 50TB of snapshots for instances that no longer exist.

How to find them:
aws ec2 describe-snapshots --owner-ids self \
  --query 'Snapshots[*].{ID:SnapshotId,Size:VolumeSize,Start:StartTime,VolumeId:VolumeId}'

Look for:

  • Snapshots older than your retention policy
  • Snapshots from deleted volumes
  • Automated snapshots without lifecycle policies

The fix:
  • Implement lifecycle policies via Data Lifecycle Manager
  • Delete snapshots from terminated instances
  • Review and reduce retention periods

5. Over-Provisioned IOPS

io1/io2 volumes charge for provisioned IOPS. If you provision 10,000 IOPS but use 500, you're wasting money.

How to find them: Check CloudWatch for VolumeReadOps and VolumeWriteOps.

Provisioned IOPS >> Actual IOPS = waste.

The fix:
  • Reduce provisioned IOPS to match actual needs (with headroom)
  • Consider switching to gp3 (3,000 IOPS included, scale up to 16,000)

The gp2 → gp3 Migration

If you're still on gp2, this is a quick win.

gp3 is:

  • 20% cheaper per GB
  • 3,000 IOPS baseline (vs. gp2's size-dependent IOPS)
  • Separately configurable IOPS and throughput

Migration is online — no downtime required.

aws ec2 modify-volume \
  --volume-id vol-xxx \
  --volume-type gp3

For most volumes, this is free money.

Building an EBS Hygiene Practice

Weekly: Unattached Volume Review

Run the unattached volume query. Review anything new. Delete or justify.

Monthly: Snapshot Audit

Check snapshot growth. Verify lifecycle policies are working. Delete orphaned snapshots.

Quarterly: Volume Type Review

Are you using the right types? gp3 vs gp2? io2 vs gp3? st1 for cold data?

On Instance Termination: Volume Cleanup

When instances die, check their volumes. Don't let them become orphans.

Automation Wins

Data Lifecycle Manager

Set up DLM policies to:

  • Automatically snapshot volumes
  • Automatically delete old snapshots
  • Keep only what you need

This is free and built into AWS.

CloudWatch Alarms

Alert on:

  • Volumes with zero I/O for 7+ days
  • Volumes at 90%+ capacity
  • Snapshots exceeding retention thresholds

Tagging and Accountability

Tag volumes with owner and purpose. When an owner leaves, review their volumes.

The Bottom Line

EBS waste is boring. It's not as dramatic as a forgotten RDS instance.

But boring waste adds up. Thousands per month, quietly, without anyone noticing.

Spend an hour auditing your EBS. You'll find money.

LET US HELP YOU
CUSTOMER
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Prefer to email us directly? support@finfan.cloud

We typically respond within 24 hours during business days.