Why this matters
Block storage is the quiet line on an AWS bill. Instances are visible and easy to stop. EBS volumes and snapshots sit in the background and keep billing after the work they supported is gone. A test instance terminated last quarter can still leave a volume and a stack of snapshots behind.
The cost has three parts: capacity, provisioned IOPS and throughput, and snapshots. A gp2 volume ties IOPS to size, so teams over-size volumes to get the performance they need. That buys capacity nobody stores data in. Snapshots are incremental, but each one keeps the blocks that changed since the previous one, so a daily policy on a busy volume builds a long bill.
Snapshots also outlive their source. Deregistering an AMI does not delete the snapshots behind it. Cross-region copies add another set. Fast snapshot restore adds a per-snapshot, per-AZ charge that few workloads need all the time. The work is mostly inventory and hygiene.
Before you start
You need read access to EC2 and Cost Explorer in every region you use. Cost Explorer shows totals by service. For volume-level detail, pull the Cost and Usage Report and filter on line_item_product_code for EC2, then on usage types that start with EBS.
Build a list before you change anything. DescribeVolumes with filters for state and attachment status, and DescribeSnapshots with OwnerIds=self, give you the inventory. Run both in every region, including the ones you think are empty. A forgotten pilot region can hold volumes and snapshots for years.
Agree on a deletion window. An unattached volume may be a standby disk for a database failover. Check tags, check CloudTrail for the detachment event, and ask the owner. For snapshots, check whether an AMI, a Data Lifecycle Manager policy or a restore runbook references them. Report first, then change.
How to do it
Start with the free wins: volumes nobody uses and snapshots nobody needs. Then fix volume type and size. Then put guardrails around snapshots so the problem does not come back next quarter. Every step is reversible except deletion, so keep a short record of what you removed.
Use Elastic Volumes to change type and size online. You can modify a gp2 volume to gp3 without detaching it, and you can raise IOPS or throughput later. The change may cause a brief I/O pause, so schedule it for anything latency sensitive. You cannot shrink a volume. You copy data to a smaller one instead.
Snapshots reward housekeeping. Run fstrim on Linux or Optimize-Volume -ReTrim on Windows before a snapshot so deleted blocks are released. Use the archive tier for snapshots you keep only for compliance, and accept slower restores. Use Recycle Bin with short retention, because deleted snapshots in the bin still bill.
- Inventory volumes and snapshots by region. Run DescribeVolumes and DescribeSnapshots in every region and export size, type, state, age and tags. Include the volume ID on each snapshot so you can see which snapshots have a live parent.
- Remove unattached volumes. Filter for volumes in the available state and age them for at least two weeks. Confirm the owner through tags or CloudTrail, take a final snapshot if the data matters, then delete the volume.
- Move gp2 volumes to gp3. Modify each gp2 volume to gp3 with Elastic Volumes. Keep the default 3000 IOPS and 125 MB/s unless CloudWatch shows queue depth or burst balance problems, then add only the IOPS you need.
- Right-size provisioned IOPS. Check AWS Compute Optimizer and CloudWatch VolumeReadBytes, VolumeWriteBytes and VolumeQueueLength over 30 days. If the volume runs below its provisioned IOPS and throughput, lower those settings before you touch capacity.
- Release free space before snapshotting. Run fstrim -av on Linux or Optimize-Volume -DriveLetter D -ReTrim on Windows, then confirm with df or Get-Volume. Snapshots stop paying for blocks the filesystem has actually released.
- Archive cold snapshots. Move snapshots kept for audit or legal hold to the archive tier and tag them with an expiry date. Keep recent restore points in the standard tier so recovery stays fast.
- Replace ad hoc snapshots with DLM. Create Data Lifecycle Manager policies per tag, with a schedule, a retention count and a copy rule only where you need cross-region recovery. The policy tag makes its snapshots easy to find.
- Turn off fast snapshot restore where it is not needed. The feature is charged per snapshot per availability zone. Enable it only for volumes that must recover in seconds, and disable it on development, staging and old DR copies.
How to check it worked
Give it a full billing cycle. EBS charges are prorated, so a mid-month change shows a partial saving. In Cost Explorer, group by usage type and filter to EBS. Watch VolumeUsage.gp3, VolumeUsage.gp2, SnapshotUsage, SnapshotArchiveUsage and the P-IOPS lines for io1 and io2. The gp2 line should fall toward zero.
For volume-level proof, check CloudWatch after each migration. VolumeQueueLength should stay near zero, and VolumeThroughputPercentage should stay under the limit you provisioned. If latency rose, add IOPS or throughput back before you chase more savings. A low storage bill with a slow database is not a win.
For snapshots, count them by tag and by age. A DLM policy with a retention count should hold the count steady. Restore one archive snapshot to a scratch volume to prove the path works. Check that the recycle bin is not holding a large backlog, and review tag coverage monthly.
Mistakes to avoid
Deregistering an AMI does not delete its snapshots. People clean up the image list and assume the bill follows. Delete the backing snapshots separately after you confirm no launch template or Auto Scaling group references the AMI.
Deleting a snapshot does not always free the space you expect. Later snapshots reference blocks in earlier ones, so removing a middle snapshot keeps the blocks that newer snapshots still need. Retire the whole chain when you retire a workload.
You cannot shrink a volume. If you need a smaller one, create it, copy the filesystem with rsync or a block tool, and cut over. Do not resize the filesystem first and hope the volume follows.
Long Recycle Bin retention and always-on fast snapshot restore are the quiet traps. Both protect data, and both bill for protection you may not need everywhere. Set the shortest window that covers a real mistake. If you want a second pair of eyes, a Cloud cost audit is a two-week read-only review at a fixed price of $4,500 that ranks storage and idle resource findings by monthly saving. It is one option among others.
Frequently asked questions
Do EBS snapshots still cost money after the volume is deleted?
Yes. A snapshot is independent of the volume once it is created. It keeps billing until you delete it, even if the instance and volume are long gone. Tag snapshots at creation so you can find the orphans later.
How do I find unused EBS volumes?
Filter DescribeVolumes for state available, then check age, tags and CloudTrail detachment events. AWS Trusted Advisor also has an underutilized EBS volumes check. Confirm with the owner before you delete anything.
How long does an EBS snapshot archive restore take?
Hours, not minutes. Plan for up to 72 hours for a large archive restore, so keep recent restore points in the standard tier. Test one restore before you move a whole retention set to archive.