TellHound

The AWS charge nobody notices: Elastic IPs you stopped using

· 5 min read · TellHound
Short answer

An Elastic IP costs $0.005 per hour — about $3.65 a month — whether or not it is attached to anything. Since 1 February 2024 AWS charges for ALL public IPv4 addresses, in-use ones included, so the old advice to 'just attach it' no longer avoids the charge. Find idle ones with: aws ec2 describe-addresses --query 'Addresses[?AssociationId==null]'. Releasing one is instant and free, but you cannot get the same address back.

This is the dullest item on any cost report, and one of the most common. It is worth five minutes for two reasons. The fix is a single command. And most of the advice written about it is now wrong.

What does an Elastic IP actually cost?

$0.005 per hour. That is $3.65 in a 30-day month, or roughly $44 a year, per address.

One address costs almost nothing. It appears on almost every account we look at because they build up over time. A load balancer gets replaced. A NAT gateway is migrated. A bastion host is retired during a migration nobody finished. Each one leaves an address behind, and nothing ever tells you.

On one account we found eight of them. That is $29.20 a month for nothing. Not a large sum — but it had been billing for over a year. Every one of them pointed at infrastructure that no longer existed.

The advice you will find elsewhere is out of date

Search for this and you will find many pages saying the same thing. AWS only charges for Elastic IPs that are not attached to a running instance. So attach it, or release it.

That was true until 1 February 2024. Since then AWS charges $0.005/hour for every public IPv4 address, whether it is attached to a running instance or not. The in-use exemption is gone.

Two things follow from that:

  • Attaching an idle EIP no longer avoids the charge. If the old advice is what stopped you releasing one, that reasoning has expired.
  • Your public IPv4 bill is now a line item worth reading, not just the idle ones. Every load balancer, NAT gateway and public instance carries the cost.

If you have not looked at this since early 2024, the number is larger than you remember.

How do I find idle Elastic IPs?

One command, no tooling:

aws ec2 describe-addresses \
  --query 'Addresses[?AssociationId==null].{ip:PublicIp,alloc:AllocationId,name:Tags[?Key==`Name`].Value|[0]}' \
  --output table

AssociationId == null is the whole test: the address is allocated to you and attached to nothing.

Elastic IPs are regional. Forgotten ones are usually in a region you set up once and never opened again, so check all of them:

for r in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
  n=$(aws ec2 describe-addresses --region "$r" \
        --query 'length(Addresses[?AssociationId==null])' --output text 2>/dev/null)
  [ "$n" != "0" ] && [ -n "$n" ] && echo "$r: $n idle"
done

That loop is worth running even if you are confident. us-east-1 is rarely the surprise; eu-west-1 from a launch three years ago usually is.

What does it cost me to fix?

aws ec2 release-address --allocation-id eipalloc-0123456789abcdef0

Instant, free, and it stops the meter immediately.

One thing to be careful about: you cannot get the same address back. Once released it returns to the AWS pool and someone else may take it within minutes. Before releasing, check whether the address is:

  • In a DNS record anywhere — including a customer's DNS you do not control. This is the most common cause of trouble. If a partner allowlisted your IP, or pointed a record at it, releasing it breaks them. Nothing warns you, and you usually find out days later.
  • In a firewall allowlist — yours or a third party's.
  • In a payment provider or API allowlist. Several require a static source IP and changing it is a support ticket, not a config edit.

If you cannot rule those out, do it in two steps. Tag the address pending-release-YYYY-MM-DD and leave it for two weeks. Then release it. Paying $3.65 for two more weeks is cheaper than causing your own outage.

Why does nothing tell you about this?

Because no component is failing. The address exists, it is allocated, it is billing. That is all correct behaviour.

AWS Cost Explorer will show it if you go looking, aggregated into EC2-Other, which is one of the least legible line items on the bill. Trusted Advisor does flag idle Elastic IPs on the paid support tiers. Neither will interrupt you about $3.65, and neither knows whether the address is genuinely abandoned or deliberately reserved.

Everything in this post needs only a read-only role. ec2:DescribeAddresses returns the allocation, its association and its tags. Finding idle addresses needs no permission to change anything. If you are deciding whether to give a tool that access, we wrote about exactly what a read-only cross-account role can and cannot see.

Small cloud waste usually has this shape. Each item is too small to alarm on. Together they add up. And nothing finds them, because finding them means looking for what is missing — an association that is not there — rather than for a problem that is.

The wider check worth running

While you are in there, the same "allocated but attached to nothing" pattern applies to:

  • Unattached EBS volumes — still billed at full rate, often left by terminated instances with DeleteOnTermination set to false
  • Old snapshots with no parent volume
  • NAT gateways in subnets with no traffic — $0.045/hour, roughly $32/month each, which makes a forgotten one an order of magnitude worse than an EIP
  • Load balancers with no healthy targets, or no listeners at all

Every one of those bills you for existing, not for doing anything. They are the easiest savings on any AWS account. They are also the least likely to be found. To find them you have to ask what is not connected to anything, and dashboards are not built to answer that.

The same blind spot has a more expensive version. There, the cost is not a wasted $3.65 but a tier that cannot grow. Two resources are each correct on their own, and wrong only together. That is what happens when an ECS capacity provider reports managed scaling over an Auto Scaling group that is pinned and cannot act. Nothing fails. Nothing alarms. The tier simply never scales.

Want this checked on your own account?

TellHound connects through a read-only cross-account role — no agents, no access keys — and reports findings like this one with the evidence attached.

Start a 14-day trial More posts