Skip to main content
Back to the Azure Footguns Database
CostGovernanceHighCommonAZF-0012

An App Service Plan with zero apps still bills its full tier rate

An App Service Plan bills for its reserved compute tier, not for the apps on it. Delete every app and the plan keeps charging the full rate for hosting nothing.

Footgun ID
AZF-0012 (Azure Footgun No. 12)
Azure service
Azure App Service
Resource type
Microsoft.Web/serverfarms
Updated
July 1, 2026

What it is

An App Service Plan (server farm) on a paid tier that hosts zero apps. The plan is the reserved compute your web apps, function apps, and API apps run on, and it bills on that reserved tier whether one app is running on it or none at all.

Impact (cost)
~$55/mo (B1) to ~$146/mo (P1v2) at list price with no apps hosted
Basis: Azure list price. Figures are estimates, not measurements.

Why it happens

The billing unit in App Service is the plan, not the app. Deleting a web app or function app removes the app, but the plan it sat on survives as a separate resource on its own tier. Azure prompts you to delete the plan when you remove the last app, but the prompt is easy to skip, and scripts and pipelines that tear down apps rarely tear down the plan.

The result is a paid plan with numberOfSites at zero: no apps, full tier charge. Test environments, decommissioned services, and migrations all leave these behind, and an empty plan looks no different from a busy one in a resource list.

What it costs / blast radius

A paid plan bills its tier flat, regardless of load: roughly $55/month for Basic B1, $70/month for Standard S1, and $146/month for Premium P1v2 at list price. (List price; region, tier, and contract vary.) An empty Premium plan is about $1,750/year for hosting nothing. Because the charge is per plan, a handful of forgotten empty plans across subscriptions adds up faster than the individual line items suggest.

See it

Find them: paid App Service Plans hosting zero apps
Resources
| where type =~ 'microsoft.web/serverfarms'
| where toint(properties.numberOfSites) == 0
| where tostring(sku.tier) !in~ ('Free', 'Shared')
| project name, resourceGroup, subscriptionId, location,
          tier = sku.tier, size = sku.name,
          apps = properties.numberOfSites
Fix: confirm no apps depend on it, then delete the plan
# The plan is a separate resource from its apps — delete it directly
az appservice plan delete --name plan-legacy-api --resource-group rg-prod --yes

How StratoLens helps

StratoLens checks every App Service Plan across every subscription, flags the paid ones hosting zero apps, and shows the tier rate they're burning plus how long they've sat empty. You don't have to remember that a plan outlives its apps or hunt for the ones a pipeline left behind; the check runs continuously inside your own tenant.

Start Your 28-Day Free Trial

Every feature unlocked. Deploys to your Azure tenant. No data leaves your tenant.

Available now on the Azure Marketplace.

Built for Azure infrastructure teams who need complete visibility across their entire estate.