← All episodes

Episode 11 · October 19, 2026

Unattached EBS Volumes: The Per-GB-Month Bill After the Instance Is Gone

When you terminate an EC2 instance, a volume that was not set to delete on termination stays behind in the available state and keeps billing per GB-month, attached or not. This episode walks through the billing mechanic, how to find unattached volumes by filtering on the available status, why available never proves unused, and why to snapshot before deleting. Find this waste on your own machine, read-only: pip install cloudcostwise

Unattached EBS Volumes: The Per-GB-Month Bill After the Instance Is Gone

Read the related post

Transcript

Auto-generated from the audio. The hosts are AI-generated voices; mistakes in the transcript are possible.

So you terminate an EC2 instance and, you know, you naturally assume the billing just stops. But watch out for that. If the attached volume has its delete on termination attribute set to false, it actually stays behind. Yeah, it enters a state called available. Right.

Welcome to this deep dive. Today we are looking at your AWS documentation and pricing notes to figure out why cloud environments silently bleed money. And our mission is to help you plug those exact leaks. Exactly. That is the goal.

So, I mean, I have to ask, why on earth does AWS keep charging for a drive that is not even plugged into anything? Well, because Amazon EBS bills for provision capacity, not used capacity. Oh, I see. Yeah, you are paying for the space and performance they reserved for you, regardless of whether that volume is actually attached to an instance. It bills per second with a 60 second minimum.

And that applies to performance too, right? Right. With GP3 volumes, it is not just the storage. Every bit of performance, like your provisioned IOPS and your throughput is on the meter, completely independent of attachment. Wow.

So it is like renting a parking space. Whether your car is parked there or not, you are still paying for the pavement. That is a great way to put it, honestly. To put this into perspective, with AWS's own example, in a region that charges a 2000 gigabyte GP2 volume provisioned for 12 hours is $3.33. Exactly right.

So let's just add up quietly. For GP2, it is 10 cents per gigabyte per month. Yeah. And for GP3, you are looking at 8 cents per gigabyte per month, plus half a cent per IOPS per month and 6 cents per megabyte per second per month. That is incredibly frustrating.

Yeah. Mostly because these unattached volumes have no owner assigned by default. No, they do not. There are no built-in alarms that go off when one gets left behind. The cost just blends into your massive monthly bill.

It is basically like a ghost ship. They are floating in your AWS account. They really do hide in plain sight. But listen, you can track them down yourself. How do we actually find them?

If you query the command line with AWS EC2 describe-volumes and filter for the state available, you will see a list of these detached drives. Okay, wait. Available sounds like it is just an unplugged hard drive sitting on a desk somewhere, totally safe to throw away. I know it sounds that way. No, unplugged actually means unused.

That is the trap right there. Available only means it is not attached at this exact moment. It never proves the volume is genuinely unused. Oh, so it could still be needed by something. Exactly.

Think about the underlying mechanics. An automated launch script, a boot script, or even a disaster recovery runbook could still reference that exact volume ID. So if a server crashes tomorrow at 3 in the morning, the fallback plan might be hard-coded to reach for that specific volume. Yes. And if you just deleted it to stop the billing, the whole recovery fails.

You must check for those references before deleting anything. Right, which means you are in a bit of a catch-22. You want to stop the billing, but you cannot risk breaking your infrastructure. Your safety net here is taking a snapshot first. And because snapshots only bill for the data you actually stored, not the massive provision size.

Standard snapshot storage is 5 cents per gigabyte month. Right. And if it is a fallback snapshot, you will rarely ever need to restore. You can move it to the archive tier. Oh, what is the rate for the archive tier?

That rate is 1.25 cents per gigabyte month, about a quarter of the standard snapshot price. Just keep in mind that the archive tier requires a 90-day minimum retention period. That makes perfect sense as a backup. So we initiate the snapshot, but knowing AWS, I am guessing we cannot just hit delete on the volume immediately. Good instinct.

After you initiate it, you must wait until the snapshots state, is completed. Do not delete the underlying volume while the snapshot just says available. Got it. Once it is fully completed, we finally delete the detached volume. Yes.

In the console, you just navigate to volumes, choose actions, delete volume, and type delete to confirm. Or from the command line, you run AWS EC2 delete dash volume, volume ID. Yes, and the volume must be detached for that to work. And there is one more mechanical detail to watch out for, which is the recycle bin. Oh, right.

The recycle bin. If a recycle bin retention rule matches your volume, that rule intercepts the deletion. The volume gets kept in the bin instead of being immediately destroyed. Interesting. But once it is truly deleted, the data is gone forever, except through that snapshot.

And if you ever do need to restore from that snapshot, it creates a completely new volume with a brand new volume ID. Exactly. To easily spot these detached volumes in the first place, try the free, source-available, CloudWise command line scanner. Yeah, it is a great tool. It is installed with pip install cloudcostwise, runs locally and read-only on your own machine, covers about 20 AWS services, and flags unattached volumes.

And nothing is sent to CloudWise. Which really leaves you pondering what other infrastructure is sitting in an available state in your environment, quietly ticking up the bill while waiting for a server that no longer exists.

Find this waste in your own account, read-only, on your own machine: pip install cloudcostwise