Azure budgets and alerts

05 Oct 2026

Budgets and alerts that fire before the invoice does

If the first time anyone hears about an overspend is when the invoice lands, the cloud didn't fail. The process did. Azure gives you three alarms for cost, and most tenants set up exactly one of them: a monthly budget with an email at 80%, sent to someone who left last spring. The three alarms answer different questions, run on different clocks, and fail in different ways. This compares them side by side, so you can see which one is actually guarding each subscription.

8–24h
before usage reaches Cost Management (EA/MCA)
24h
between budget evaluations
36h
after the day ends, anomaly detection runs
0
resources a budget stops on its own

Three alarms, three different questions

A budget with an actual cost threshold asks "have we already spent X% of the amount?" A forecasted threshold on the same budget asks "at this rate, will we?" An anomaly alert doesn't know your budget at all. It asks "is today's spend unusual compared with the last 60 days?" Those three questions catch three different failures: the slow leak, the trend you could still correct, and the spike that is small against the monthly total but huge against a normal Tuesday.

Budget — actual Budget — forecast Anomaly alert
Fires when Accrued cost crosses a % of the budget Projected cost crosses a % of the budget A day falls outside the range expected from the last 60 days
Scopes Management group, subscription, resource group, plus EA/MCA billing scopes Subscription only
Can trigger automation Yes, through an action group, but only at subscription and resource group scope No. Email only, sent once, when it's detected
Limits Up to 5 thresholds and 5 email addresses per budget 5 alert rules per subscription
Silent failure The budget passes its expiration date and is deleted The rule's creator loses access, and the emails stop

Enterprise Agreement customers also get two alerts they don't configure: credit alerts at 90% and 100% of the Azure Prepayment, and department spending quota alerts. Neither exists on a Microsoft Customer Agreement or pay-as-you-go, so don't build a runbook that assumes them.

How late is "before"?

No cost alert is real-time, and the timing is documented. For EA and MCA, usage typically reaches Cost Management within 8–24 hours, and pay-as-you-go can take up to 72. Budgets are then evaluated every 24 hours, and the email normally goes out within an hour of the evaluation. Anomaly detection runs 36 hours after the end of the UTC day, so it can see the whole day. Here's what that means for a scale-out that starts at 10:00 UTC on a Monday:

A SPIKE AT 10:00 UTC MONDAY — WHEN EACH SIGNAL CAN REACH YOU (EA/MCA) spike starts UTC day ends Usage recorded meter → Cost Management 8–24h Budget alert daily evaluation + 1h email best ~9h · worst ~49h Anomaly alert day closes + 36h ~50h 0h 24h 48h Pay-as-you-go: usage can take up to 72h to land, so add up to two days to every bar. The invoice comes after month close.

The honest summary is that any cost alarm is about two days behind the event that caused it. That's fine for a VM someone forgot over the weekend, and useless for a misconfigured job burning money by the hour. That second case is what Azure Monitor metric alerts and quotas are for, not Cost Management. The real question is whether you hear about it in two days or in five weeks, and that depends on which threshold you set.

Why the 80% email gets ignored

Alert fatigue in budgets is built into the setup, not a matter of people being careless. Budgets reset to zero at the start of every period. A healthy subscription crosses 50% of its monthly budget around the 15th and 80% around the 24th, every month, on schedule. So an actual-cost threshold below your normal end-of-month level is really a calendar reminder, and after the third month nobody reads it.

ONE BUDGET, TWO MONTHS — ILLUSTRATIVE 50% 100% 0 day 1 day 15 day 30 Actual 50% normal month, fires every month Forecast 100% ~day 6: time to act Actual 100% day 24: money already spent Blue: a normal month ending near 95%. Red: a month running 25% hot from the start.

The forecast threshold has the opposite property. It stays quiet in a normal month and speaks early in a bad one. That makes it the only threshold that fires before the money is gone. Two more sources of noise are worth filtering out. Budget evaluations now include reservation and other purchase data and use actual cost, not amortised cost. A three-year reservation bought on the 3rd can push the budget past 100% on the 4th. If the budget is meant to watch consumption, add the filters Microsoft suggests: Publisher Type: Azure and Charge Type: Usage.

The rule of thumb
Every threshold should map to someone who does something different when it fires. Forecast at 100%: the owner investigates. Actual at 100%: the owner's manager hears about it. Actual at 110–120%: the action group runs. A threshold that nobody acts on is just noise.

Per subscription or per resource group?

Put each budget where its email can reach the person who can fix the cause. Subscription budgets suit the platform team. Resource group budgets suit application owners, and you'll need them if you want an action group: action groups only work at subscription and resource group scope. A management group budget can send email and nothing else. It also comes with a single-currency requirement: if subscriptions billed in different currencies sit under the same management group, Microsoft warns that you may miss alerts. Budget filters can narrow a subscription budget to a set of resource groups or a service. That's useful, as long as the tags you'd filter on actually reach the cost data.

Anomaly alerts can't go to resource groups. Create one per subscription, and create it as a service principal through the Scheduled Actions API. The reason: the email is sent based on the creator's access at the time it goes out. A rule created by an engineer stops working the day that engineer changes team.

Wiring the action group without shooting yourself

Microsoft's own budget automation scenario uses a budget, an action group, a Logic App and an Automation runbook. At 80% it stops the VMs in a resource group called Optional, and at 100% it stops every VM. That's sensible for dev/test, where the money leaks out of resources nobody remembers starting. In production it means a budget can switch off a service. Make sure the person who sets the threshold is the person who would get the call at 3am. Three more traps:

  • PowerShell budgets are mute. The tutorial says it plainly: budgets created with PowerShell don't send notifications. Use the REST API, Bicep or the portal.
  • Expiry means deletion. A budget with an end date is deleted when that date passes, without telling anyone. Set the end date far ahead, and review the list every quarter.
  • The budget doesn't stop anything. "Resources aren't affected, and your consumption isn't stopped." The action group is the only part of this setup that actually does something.
Sources

A budget tells you a threshold was crossed. It doesn't tell you what moved. GraphPaaS reads Azure spend per tenant and breaks it down by resource, type and resource group, with a month-by-month drill-down. When the forecast alert arrives on day 6, the follow-up question ("which resource group?") takes one click instead of an afternoon in Cost Analysis. For an MSP, that works across every client tenant from the same screen.

GraphPaaS

When the alert fires, see which resource group moved, in every tenant you manage.

Break down your Azure bill →

Newsletter

Get the next article by email

Practical M365 & Azure cost pieces like this one. No spam, unsubscribe anytime.