Idle load balancers: the ~$16/month each you forgot to delete
Short version: An Application or Network Load Balancer costs ~$0.0225/hour - about $16/month - just to exist, plus capacity units. Classic Load Balancers run ~$18/month. Load balancers outlive the services behind them: the app gets torn down, the ALB keeps billing. Here is how to find load balancers with no real traffic or no healthy targets, and remove them safely.
Why idle load balancers linger
The hourly base charge is fixed - an ALB with zero requests bills the same ~$16/month as a busy one. Load balancers are usually created early (with an app or an IaC module) and deleted last, if ever. A handful of abandoned ALBs from old environments is real, recurring money.
Step 1 - List load balancers and their traffic
aws elbv2 describe-load-balancers \
--query 'LoadBalancers[].{Name:LoadBalancerName,Type:Type,ARN:LoadBalancerArn}' \
--output table
For an ALB, check request volume over the last 7 days (the metric dimension is the
tail of the ARN, e.g. app/my-alb/50dc6c495c0c9188):
aws cloudwatch get-metric-statistics \
--namespace AWS/ApplicationELB \
--metric-name RequestCount \
--dimensions Name=LoadBalancer,Value=app/my-alb/50dc6c495c0c9188 \
--start-time "$(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ)" \
--end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--period 86400 --statistics Sum \
--query 'Datapoints[].Sum'
Near-zero request counts over a week is a strong idle signal. (For NLBs, use the
AWS/NetworkELB namespace and ActiveFlowCount.)
Step 2 - Check for empty or unhealthy target groups
A load balancer with no healthy targets is doing nothing useful:
for tg in $(aws elbv2 describe-target-groups \
--load-balancer-arn <lb-arn> \
--query 'TargetGroups[].TargetGroupArn' --output text); do
echo "== $tg =="
aws elbv2 describe-target-health --target-group-arn "$tg" \
--query 'TargetHealthDescriptions[].TargetHealth.State' --output text
done
Empty output (no targets) or all unhealthy alongside near-zero requests is a
confident "delete me."
Step 3 - Delete safely
aws elbv2 delete-load-balancer --load-balancer-arn <lb-arn>
Caveat: a load balancer with no requests is not always dead - it might be a disaster-recovery endpoint, a rarely-hit admin panel, or the target of a DNS record that something depends on. Before deleting, check Route 53 (and any external DNS) for records pointing at the load balancer's DNS name, and confirm nothing references it:
aws elbv2 describe-load-balancers --load-balancer-arn <lb-arn> \
--query 'LoadBalancers[].DNSName' --output text
Then grep your DNS zones for that name. No references + no traffic + no healthy targets = safe to remove.
Do it automatically
Cloud Cost Analyzer's idle-load-balancer rule flags load balancers serving fewer
than 100 requests/day over a 7-day window, so you are not manually pulling CloudWatch
for each one - alongside 89 other cost rules:
curl -sSL https://releases.dragonfractal.com/install.sh | sh
cca scan --provider aws
The agent runs in your environment with read-only access, so your AWS credentials never leave it. See the AWS setup and required IAM permissions
CLI Reference
aws elbv2 describe-load-balancersaws elbv2 delete-load-balanceraws ec2 describe-target-group-health