# Azure Load Balancer with No Backends

> Only Standard and Gateway load balancers carry an hourly fee, so ZopNight skips Basic SKUs outright, then requires an empty backend pool plus 30 days of ByteCount under 100 KB and PacketCount under 1,000 before recommending deletion. AKS-managed load balancers named kubernetes are always exempt.

Source: https://zop.dev/integrations/azure/recommendations/azure-load-balancer-with-no-backends
Updated: 2026-08-19

---

## Backend pool first, traffic second

An Azure Load Balancer with no backend pool members forwards to nothing, but "no backends
right now" is not proof of abandonment. ZopNight reads the discoverer's backend-target
enrichment: a populated targets list means the pool has members and the rule stops immediately.
Only when the pool is empty does the data path get examined, and traffic must also be flat
before the delete is recommended. Configuration state and observed behavior have to agree.

## Two floors sized for probe chatter

Even an idle load balancer registers bytes and packets from health probes, keepalives, and SNAT
housekeeping. The floors (roughly 100 KB of `ByteCount` and 1,000 packets of `PacketCount` per
aggregation window) absorb that chatter while sitting far below any served payload. Average
and maximum both must stay under the floor across 30 days of coverage; one busy hour means real
traffic flowed.

## Why Basic SKUs and kubernetes LBs never appear

A Basic load balancer is free, so deleting one saves $0 and ZopNight abstains rather than
fabricate a figure. The rule reclaims the fixed hourly fee only Standard and Gateway SKUs
carry. Separately, AKS provisions load balancers the cluster depends on: any LB whose name
contains kubernetes-internal, or is exactly `kubernetes`, is structurally required for cluster
ingress and outbound SNAT and is skipped by exact-match design.

## Inspect pool and traffic together

```bash
az network lb address-pool list --lb-name <lb> -g <rg> \
  --query "[].loadBalancerBackendAddresses" -o table
az monitor metrics list \
  --resource "$(az network lb show -n <lb> -g <rg> --query id -o tsv)" \
  --metric ByteCount PacketCount \
  --interval PT1H --offset 30d --aggregation Average Maximum
```

## Conditions that suppress the finding

Populated backend pool, Basic SKU, protected kubernetes naming, a missing ByteCount series,
under 30 days of coverage, any traffic at or above either floor, or an unpriced cost. Each of those
returns silence. Backend health-probe availability is attached as context when present, but
never gates the decision.

## After the delete

Frontend public IPs survive the load balancer and keep billing on their own; delete or
repurpose them in the same change. Detection relies on Reader and Monitoring Reader only.
