App Service plans whose busiest hour stays under 40% CPU
What does ZopNight detect here?
Peak, not average, decides a safe App Service downsize: ZopNight only flags a plan when its hourly-maximum CPU never reached 40% across 30 full days of coverage and memory stayed under 50%. The saving is the real rate gap to the tier one rung down, on matching Linux or Windows pricing.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1310 |
| Category | rightsizing |
| Severity | medium |
| Metric | none — pure configuration read |
| Source | appservice_rightsizing.go |
Where it applies
Averages lie about web workloads
Web traffic is spiky, and a plan averaging 12% CPU can still hit 90% every lunchtime. Downsize on the average and those peaks start timing out. This rule gates on the trustworthy hourly maximum instead: only when the busiest hour in 30 days stayed under 40% CPU does the plan qualify, because even that busiest hour would fit inside a one-rung-smaller tier’s headroom. Deliberately, there is no zero-traffic test here; a lightly-but-continuously used plan can still be badly oversized, and the empty-plan case belongs to a separate idle rule.
Two ways to be wrongly small
Memory guards the decision alongside CPU: when the plan’s memory series averages 50% or more, the finding is suppressed. Memory-bound plans get slower, not cheaper, on fewer cores. And the CPU series must carry a full 30 days of hourly-maximum coverage before any of it is believed; freshly monitored plans read artificially low for lack of data.
Rates matched to your OS, or nothing
App Service pricing differs between Linux and Windows plans, so the rule looks up both the current tier and the one-rung-smaller target under OS-specific rate keys. The recommendation ships only when both real rates exist and produce a sane delta: a P2v3 to P1v3 step, priced from your region’s actual rates. Missing rates mean abstain; the rule never falls back to an estimated percentage of the bill.
Replay the peak analysis
az monitor metrics list \ --resource "$(az appservice plan show -n <plan> -g <rg> --query id -o tsv)" \ --metric CpuPercentage MemoryPercentage \ --interval PT1H --offset 30d --aggregation Maximum AverageScan the Maximum column for any hour at 40 or above.
Downsizing a live plan
A tier change applies to every app on the plan and takes effect within minutes, no restart required in most cases. Move down one rung, watch response times and the CPU peak for a week, and repeat if the new peak still clears the bar comfortably.
Detection inputs
Reader for plan properties, Monitoring Reader for CPU and memory series, Cost Management Reader for the billed baseline the delta applies to.