Skip to main content
idle · azure

App Service plans hosting zero apps while billing reserved compute

resource types
1
rule IDs covered
1
severity
medium

What does ZopNight detect here?

An App Service plan with numberOfSites at 0 pays its full tier fee to host nothing. ZopNight reads that count from Resource Graph, then holds fire if the plan's CpuPercentage series shows 5% or more average or peak over a trustworthy 30-day window. Recent activity means apps were just removed, not abandoned.

Signal and threshold

How ZopNight evaluates App Service plans hosting zero apps while billing reserved compute.
Field Value
Rule IDsRC-222
Categoryidle
Severitymedium
Metricnone — pure configuration read
Sourceappservice_idle.go

Empty plans are what app deletion leaves behind

Deleting a web app in Azure does not delete the App Service plan under it. The plan (the actual billable unit) stays, reserving compute at its full tier rate with a site count of zero. ZopNight reads the authoritative numberOfSites property that Resource Graph reports for every server farm; a count of 0 is the primary signal that the tier fee is buying nothing.

Zero sites now, but busy recently: not flagged

A plan can reach zero sites minutes after a migration, mid-reshuffle, with deployment slots or hybrid connections still winding down. So the rule adds a suppression guard: when a trustworthy CpuPercentage series exists, meaning at least 30 days of coverage, and its windowed average or maximum reaches 5% or more, the delete recommendation is withheld. The plan is empty but warm, and warmth earns it a reprieve until next cycle.

The reverse does not hold: a missing CPU series does not block the finding. An empty plan with no telemetry genuinely has nothing running on it, and the site count stands on its own.

Check a suspect plan in seconds

Terminal window
az appservice plan show -n <plan> -g <rg> \
--query "{sites: numberOfSites, sku: sku.name}" -o json
az monitor metrics list \
--resource "$(az appservice plan show -n <plan> -g <rg> --query id -o tsv)" \
--metric CpuPercentage --interval PT1H --offset 30d \
--aggregation Average Maximum

Two exits, one of them free

Deleting the empty plan ends the charge. The often-better move is consolidation: an empty S1 alongside a crowded S1 is an invitation to move apps into one plan and delete the other. Same monthly saving, more headroom where it counts. Either way the saving equals the plan’s full tier fee, which is how ZopNight prices it.

Where the rule stays quiet

Any hosted site, recent CPU activity at or above the 5% floor over a trustworthy window, or an unpriced tier each suppress the finding. Free and shared tiers rarely survive the cost gate, since there is little to reclaim. Reader supplies the site count, Monitoring Reader the CPU series; detection touches nothing else.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·