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.


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.