Cost OptimizationMay 25, 20264 min read

How to Find Unused AWS Resources That Are Silently Billing You

Where they hide in AWS, and how to check your account for them in a few minutes.

AWS will never tell you a resource has gone unused. It just keeps billing, quietly, until you go looking. I've written before about the second account I let run for six months before I checked what was actually inside it. This post is the practical version... exactly where unused resources hide in AWS, and how to check your own account for them.

Unattached EBS volumes

An EBS volume is the storage drive attached to your EC2 server. When you terminate the instance, AWS deletes the root volume by default, but only if "delete on termination" was left on. Any extra volume you attached later keeps its own setting, usually off, so it survives the instance and just sits there. In the EC2 console, open Volumes and check the State column. A volume marked "available" isn't attached to anything, and it's been billing you for storage the entire time regardless.

Unassociated Elastic IPs

An Elastic IP is a fixed public address AWS reserves for you specifically, so it doesn't change if you stop and restart the instance behind it. AWS charges for public IPv4 addresses by the hour these days, and an Elastic IP sitting unattached is paying that charge for nothing in return. Open the Elastic IPs page in the EC2 console. If the Associated instance column is blank, that address is doing nothing except costing you.

Stopped instances and the snapshots that outlive them

Stopping an EC2 instance stops the compute charge, but any EBS volume attached to it keeps billing for storage the whole time it's stopped. RDS, AWS's managed database service, behaves differently again. You can stop a database, but AWS automatically starts it back up after about a week whether you meant to leave it stopped or not, and you're billed as if it were running from that point on.

Snapshots are the ones people forget completely. Automated snapshots expire on a retention schedule, but manual ones don't expire on their own, ever. A snapshot you took by hand during a migration a year ago is still sitting in EC2 or RDS, still billing you for storage, until you go delete it yourself.

NAT gateways, the expensive surprise

A NAT gateway lets resources in a private subnet reach the internet without being reachable from it themselves. Useful, often necessary. It also bills by the hour, plus a separate charge for every gigabyte of data it processes, whether that traffic is doing anything meaningful or not. People build a VPC for a project, the project ends, and the NAT gateway keeps running because nobody remembers it's part of the network.

Load balancers behave the same way. An Application or Network Load Balancer bills by the hour whether it has zero healthy targets behind it or a hundred. Decommission the service and forget the load balancer, and it just keeps running, and billing, for nothing.

You can check all of this yourself. Open each console page, filter by state, do it across every region you've ever touched. It works. It also takes real time, and it's the kind of task that keeps getting pushed to next week.

Or you can ask. Once your account is connected, Liberra already has it indexed, so there's nothing to scan first. Ask it in plain English: "what's sitting unused right now?" Reads are instant and don't need approval, so it costs nothing to ask. It'll find the volumes, the IPs, the snapshots, the NAT gateways, and tell you what each one is costing you. It won't delete any of it. Deletes are physically blocked in the code, not a setting you could turn off if you wanted to. Deleting is on you, in the console, on purpose.

Founder, Liberra AI