Standard load balancers with an empty backend pool and no data-path traffic
What does ZopNight detect here?
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.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1362 |
| Category | idle |
| Severity | medium |
| Metric | none — pure configuration read |
| Source | lb_idle.go |
Where it applies
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
az network lb address-pool list --lb-name <lb> -g <rg> \ --query "[].loadBalancerBackendAddresses" -o tableaz 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 MaximumConditions 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.