AWS · Hands-on guide · Updated June 2026

How to Find (and Safely Delete) Unattached EBS Volumes in AWS


By the CloudFinOpsKit team — the people who build and maintain the AWS tool's 70+ Well-Architected cost checks. 9 min read.

Unattached EBS volumes are the most common piece of waste we find in AWS accounts — and the easiest money to recover. When an EC2 instance is terminated, any volume whose DeleteOnTermination flag was false survives. It drops into the available state, attached to nothing, billed in full. Add years of Auto Scaling churn, blue/green deploys, and "I'll clean it up later" experiments, and most accounts quietly carry a four-to-five-figure annual bill for storage nobody uses.

What an unattached volume actually costs

EBS bills for provisioned capacity, not usage — attached or not, running instance or not, the meter runs. Approximate us-east-1 list prices:

Volume typeSize~Monthly list~Annual if forgotten
gp3500 GB~$40~$480
gp2500 GB~$50~$600
io2 (500 GB + 5k IOPS)500 GB~$390~$4,700
st11 TB~$45~$540

Provisioned-IOPS (io1/io2) volumes are the painful ones — you pay for the IOPS too. And a quick win hiding in plain sight: migrating live gp2 → gp3 is ~20% cheaper for the same performance.

Method 1 — the AWS Console (quick spot-check)

  1. Open EC2 → Elastic Block Store → Volumes.
  2. Filter Volume state = available.
  3. Sort by size descending — your biggest savings are at the top.

Fine for one region in one account. It doesn't scale to an Organization, and it won't warn you about the traps below.

Method 2 — the AWS CLI (the right way at scale)

List every unattached volume in a region, biggest first:

aws ec2 describe-volumes \
  --filters Name=status,Values=available \
  --query "sort_by(Volumes,&Size)[*].{ID:VolumeId,GB:Size,Type:VolumeType,AZ:AvailabilityZone,Created:CreateTime}" \
  --output table --region us-east-1

Loop your enabled regions (volumes are regional), and for an Organization, assume a read-only role per account. The status=available filter is the key signal: a volume in-use is attached; available means it belongs to nothing.

The traps: volumes & snapshots that look orphaned but aren't

This is where cleanup scripts cause incidents. We learned these building our own scanner:

1. Snapshots that back an AMI

An EBS snapshot can be the backing store for an AMI. Delete the snapshot and the AMI can no longer launch — you've silently broken your golden image or an Auto Scaling launch template. Always deregister-image first, then delete the snapshot. Map it with aws ec2 describe-images --owners self.

2. Volumes on stopped instances

A stopped EC2 instance pays nothing for compute, but its attached EBS volumes keep billing in full. These aren't "available" (so the filter above misses them) — they're a separate finding worth its own review: if the instance has been off for months, snapshot and terminate.

3. Idle Elastic IPs

An unassociated Elastic IP bills ~$3.60/month doing nothing — and since Feb 2024 AWS bills every public IPv4 address, including attached ones. Release the idle ones: aws ec2 describe-addresses --query "Addresses[?AssociationId==null]".

4. Snapshots may be deliberate DR / compliance

Old snapshots can be intentional retention. The genuinely safe target is snapshots whose source volume no longer exists and that aren't managed by Data Lifecycle Manager or AWS Backup. Don't bulk-delete by age alone.

5. Tagged keep-list & launch templates

Exclude anything tagged DoNotDelete, and volumes referenced by an Auto Scaling launch template snapshot.

The safe deletion workflow

  1. Exclude the traps — AMI-backing snapshots, DLM/Backup-managed snapshots, DoNotDelete tags.
  2. Snapshot first. A snapshot costs a fraction of the live volume:
    aws ec2 create-snapshot --volume-id vol-0abc --description "final-before-delete"
  3. Tag and announce. aws ec2 create-tags --resources vol-0abc --tags Key=DeleteAfter,Value=2026-08-15 — then tell the owning team.
  4. Wait the grace period (14–30 days), then delete:
    aws ec2 delete-volume --volume-id vol-0abc
  5. Retire the snapshot a quarter later if nobody needed it.

Or let the scanner do all of this for you. The CloudFinOpsKit AWS Tool (one-click, read-only) finds every unattached EBS volume, idle Elastic IP and disconnected snapshot across your whole account or Organization, automatically excludes AMI-backing and Backup-managed snapshots, prices each finding from your actual Cost Explorer billed cost (with a region-accurate Price List fallback), and hands you the exact aws commands — alongside 70+ other Well-Architected checks.

Prefer the manual route first? Grab the free AWS Cost Review Checklist and make EBS cleanup a monthly habit.

Stop them coming back

FAQ

Do unattached EBS volumes really cost full price?

Yes — EBS bills provisioned GB-months (and provisioned IOPS for io1/io2) regardless of attachment or instance state. The meter only stops at deletion.

Can I just delete old snapshots to save money?

Carefully. Snapshots are cheap (they're incremental), and deleting one that backs an AMI or a Backup plan can break recovery. Target disconnected snapshots whose source volume is gone, and deregister dependent AMIs first.

What's the fastest no-risk EBS saving?

Migrate gp2 volumes to gp3 — same or better performance, ~20% cheaper, and it's a live, non-disruptive change.

Related reading: the AWS cost optimization checklist for 2026 · Savings Plans vs Reserved Instances · Amazon Bedrock cost optimization