Idle load balancers: How to Find Them and What They Cost
Idle load balancers are Application and Network Load Balancers with no healthy targets or no requests, billing hourly regardless. They are one of the most reliable sources of pure waste in an AWS account, because nothing in the console flags them and nothing fails when they exist — the bill simply stays higher than it needs to be.
This page covers what they cost, the command that lists yours, and — importantly — what to check before deleting anything.
What they are and why they linger
Elastic Load Balancing charges an hourly rate plus a capacity-unit rate. The hourly rate applies from creation to deletion with no regard for whether the load balancer has any targets, any healthy targets, or any traffic.
They survive their workloads routinely: a service is deleted, its target group empties, and the load balancer stays. Because a load balancer is normally created by someone else’s automation, nobody feels ownership of the leftover.
What they cost
At roughly $0.0225 per hour for an ALB, an idle one is about $16 a month, plus capacity units. A Network Load Balancer is a similar order. A dozen strays across environments is around $2,300 a year.
Classic Load Balancers deserve a separate look — an account still running them is usually running them by inertia, and migrating to an ALB or NLB is generally both cheaper and better.
Finding yours
# Load balancers whose target groups have no registered targets.
for arn in $(aws elbv2 describe-load-balancers \
--query 'LoadBalancers[].LoadBalancerArn' --output text); do
name=$(aws elbv2 describe-load-balancers --load-balancer-arns "$arn" \
--query 'LoadBalancers[0].LoadBalancerName' --output text)
targets=0
for tg in $(aws elbv2 describe-target-groups --load-balancer-arn "$arn" \
--query 'TargetGroups[].TargetGroupArn' --output text); do
n=$(aws elbv2 describe-target-health --target-group-arn "$tg" \
--query 'length(TargetHealthDescriptions)' --output text)
targets=$((targets + n))
done
[ "$targets" -eq 0 ] && echo "$name: NO TARGETS ($arn)"
done
# Any Classic Load Balancers still running?
aws elb describe-load-balancers \
--query 'LoadBalancerDescriptions[].{Name:LoadBalancerName,Instances:length(Instances)}' \
--output table
Cross-check with the RequestCount metric over a fortnight — a load balancer with targets but no requests is just as idle as one with none.
Before you delete
A load balancer’s DNS name may be in someone’s configuration. Deleting it breaks anything pointing at that name, including Route 53 alias records, partner integrations, and mobile clients that will not be updated quickly.
Check for alias records first:
aws route53 list-resource-record-sets --hosted-zone-id Z0123456789ABCDEFGHIJ \
--query "ResourceRecordSets[?AliasTarget.DNSName!=null].[Name,AliasTarget.DNSName]" --output text
A zero-target load balancer fronting a service that scales to zero — a scheduled batch service, a rarely-used internal tool — is doing its job. Confirm the target group’s Auto Scaling configuration before assuming abandonment.
Stopping them coming back
Create load balancers from the same IaC stack as the service they front, so destroying the service destroys the load balancer. The stragglers are almost always the ones created by hand in the console.
For internal tools that are used occasionally, consider whether an ALB is warranted at all — API Gateway, a Lambda function URL, or CloudFront may cost nothing at idle.
Related
- Idle NAT gateways — NAT gateways in subnets that no longer run anything, billing an hourly charge for a path nothing uses
- Orphaned network interfaces — ENIs left in the available state, holding IP addresses and blocking the deletion of the security groups and subnets they reference
- The whole cost-waste checklist — every category in this series
- NAT gateway cost calculator — model the largest recurring VPC charge
Prices quoted are us-east-1 list rates, last checked on 2026-08-22, and are shown with the arithmetic so you can substitute the rates for your own region. Always confirm against the AWS pricing page before acting on a number.