Azure OpenAI spend

How to keep Azure OpenAI spend under control

Azure OpenAI doesn't have a native hard spending limit, so a runaway script or a leaked credential will keep running until your subscription runs out of credit or your credit card fails. Unlike the direct OpenAI API, where you can enforce a monthly dollar ceiling, Azure expects you to govern spend through quotas, budget alerts, and identity permissions.

Keeping your bill predictable means understanding how different deployment types meter tokens, cleaning up idle fine-tuning hosting fees, and having an emergency killswitch to shut off API key access. Moving non-urgent jobs to the Batch API immediately cuts token rates by 50%, while choosing the wrong Provisioned deployment can lock you into minimum commitments of 15 to 50 Provisioned Throughput Units (PTUs) billed around the clock.

How Azure OpenAI bills tokens and capacity

Azure OpenAI pricing splits into three distinct operational models: Standard (on-demand), Provisioned Throughput Units (PTUs), and the Batch API. Standard is pay-as-you-go based on input and output tokens. Rates depend on the model, deployment type, and specific billing meters.

Standard and Provisioned deployments fall into three distribution models: Global Deployment (using the Global SKU), Data Zone Deployment (restricted to EU or US geographic boundaries), and Regional Deployment (hosted in up to 27 local regions). Where you deploy determines both latency boundaries and capacity thresholds.

If your workloads don't need real-time streaming, the Batch API offers a straight 50% discount on Global Standard Pricing. It returns completions within 24 hours and is available for global deployments and three regions. For delay-tolerant interactive workloads that don't fit the batch window, Flex processing offers discounted token rates with dedicated meters for cost analysis.

Provisioned deployments work differently. Instead of paying per token processed, you pay an hourly rate per model regardless of actual usage. PTUs guarantee capacity, but they come with strict minimum allocation sizes that will destroy a small budget if deployed carelessly. Monthly and annual reservations are available to lower that hourly cost, but the floor remains high.

Deployment modelBilling metricMinimum commitmentBest used for
Standard (Global / Data Zone / Regional)Per input and output tokenNoneVariable, real-time application traffic
Batch API (Global & 3 regions)Per token (50% off Global Standard)NoneNon-urgent jobs completed within 24 hours
Provisioned: Global & Data ZoneHourly rate per model15 PTUsPredictable production throughput
Provisioned: Regional (Full models)Hourly rate per model50 PTUsHigh-volume regional compliance (e.g. GPT-4o, GPT-5)
Provisioned: Regional (Mini models)Hourly rate per model25 PTUsHigh-volume small models (e.g. GPT-4o Mini, o4-mini)

Regional PTU minimums depend heavily on the model class. Full-sized models - including GPT-4o, GPT-4.1, o3, GPT-5, GPT-5.1, GPT-5.2, GPT-5.3 Codex, GPT-5.4, GPT-5.5, GPT-5.6, GPT-5-mini, and Fine-Tuned GPT-4o - demand a minimum of 50 PTUs. Smaller regional models like GPT-4o Mini, Fine-Tuned GPT-4o-Mini, GPT-4.1-mini, GPT-4.1-nano, o3-mini, and o4-mini require at least 25 PTUs. In contrast, Global and Data Zone deployments set the bar at 15 PTUs across listed models.

Commitment tiers are another option across Microsoft Foundry services. You pay a fixed fee for committed usage, but if your application exceeds the plan's quota, extra consumption is billed at the overage amount shown in the Azure portal when you purchase the plan.

Watch out for idle hosting and auxiliary tool meters

Surprise invoices in Azure OpenAI rarely come from simple inference alone. Idle infrastructure and assistant tools quietly generate continuous charges.

Fine-tuning hosting costs

Fine-tuning pricing consists of three stages: training, hosting, and inference. Training is billed either per token or per hour depending on the base model. Once trained, inference runs per 1,000 tokens (or per 1M tokens on standard pricing sheets) for input and output.

The trap is hosting. Hosting an Azure OpenAI fine-tuned model incurs an ongoing hourly charge per deployed model that applies even if the model sits completely idle. If you deploy a custom model for testing and leave it over the weekend, you're paying for every hour it exists. To stop unexpected hosting charges during low-usage windows, you must explicitly delete or scale down unused deployments.

Developer tier fine-tuning deployments for models like o4-mini, GPT-4.1, GPT-4.1-mini, and GPT-4.1-nano list per-token input, cached input, output, and training rates without an hourly hosting fee. But reinforcement fine-tuning for o4-mini charges per hour for training and hosting, per 1M tokens for inference, plus separate Grader token fees for GPT-4o or o3-mini.

Assistants, files, and deep research

Built-in tooling meters add their own line items:

  • File Search: Vector storage costs money per GB per day (calculating 1 GB as 2^30 bytes), though the first 1 GB is free.
  • Code Interpreter: Billed per session. A session stays active by default for one hour within the same thread. If an assistant calls Code Interpreter simultaneously across two different threads, Azure bills for two separate sessions.
  • Deep Research: Search context tokens are billed at the standard input token rate of the model being called. You also pay separately for Grounding with Bing Search and the base GPT model used to generate clarifying questions.

Keep in mind that HTTP error status codes alone don't determine whether a request is billed. If billable processing occurred before the failure, or depending on how the specific meter operates, you'll still pay for the run.

Why budgets don't stop spend (and how to track it)

Developers coming from OpenAI often expect a hard cap setting. As covered in our guide on how to set a hard spending limit on the OpenAI API, direct OpenAI accounts let you define a soft alert and a hard cutoff.

Azure OpenAI does not offer hard spending limits. Azure Cost Management provides budget alerts, but they only send notifications via email or action groups. When an Azure budget threshold triggers, traffic keeps flowing unless you build custom automation via action groups to sever access.

To complicate tracking, Cost Management records can appear with a delay depending on service ingestion timing - often lagging by 8 to 72 hours. Don't use minute-by-minute comparisons to reconcile costs; look at wider trend windows.

Navigating Azure Cost Analysis

When reviewing your spend in the Azure portal, Azure OpenAI doesn't show up as an independent service in the top-level service filter because Azure classifies it under Cognitive Services. To view it across a subscription:

  1. Open Cost Management and go to Cost Analysis.
  2. Add a filter for Service tier: Azure OpenAI.
  3. To view costs per project, filter by the project tag. Microsoft Foundry automatically tags underlying usage for Models sold by Azure (preview). Note that this attribution does not support models served through Azure Marketplace or Claude resource tags.

To inspect specific deployments in the Microsoft Foundry portal, navigate to Build > Models, pick your model, and select the Monitor tab. Remember that portal estimates only cover standard deployments (not provisioned throughput) and don't reflect custom contracted pricing or discounts.

If you need deeper internal accounting, Cost Management data can be exported to an Azure storage account on a daily, weekly, or monthly schedule.

Disabling API keys: your emergency killswitch

Because Azure lacks a built-in spending cap, leaked or compromised API keys can drain budgets rapidly. The safest defense is disabling local API key authentication entirely, requiring callers to authenticate via Microsoft Entra ID instead.

You can turn off local keys using Azure Policy with the rule Azure AI Services resources should have key access disabled (disable local authentication). In Bicep or ARM templates, set disableLocalAuth to true.

To cut off keys immediately using Azure PowerShell, run:

Set-AzCognitiveServicesAccount -ResourceGroupName "my-resource-group" -Name "my-resource-name" -DisableLocalAuth $true

You can verify the current state by checking the property:

(Get-AzCognitiveServicesAccount -ResourceGroupName "my-resource-group" -Name "my-resource-name").DisableLocalAuth

Be aware of cache propagation latency. Disabling local authentication updates the control plane immediately, but the shared gateway enforcing authentication can continue accepting previously valid keys until its cache refreshes. While propagation usually finishes in a few minutes, it can take up to several hours under certain regional loads. Verify it took effect by sending a request with the old API key; it must return an HTTP 401 with the error:

Access denied due to invalid subscription key or wrong API endpoint

To restore key access later, set -DisableLocalAuth $false. Like disabling, re-enabling keys takes from a few minutes up to several hours to propagate back out to the gateway.

Setting up automated guardrails with Costbrake

If you don't want to maintain custom Azure Action Groups or poll PowerShell scripts, Costbrake provides live spend visibility across 23 cloud and AI providers, with human-in-the-loop brakes on 18 of them, Azure included.

Azure reports finalized billing data 8 to 72 hours late, which is too slow to catch an infinite loop. Costbrake reads Cost Management every 6 hours and bridges that gap by pulling live token metrics from Azure Monitor for Azure OpenAI and AI Services accounts, pricing them at list rates within minutes.

Costbrake monitors your account on a regular schedule (hourly on Free, every 5 minutes on Pro and Team, and stepping up to every 2 minutes during an active spike). A spike alert fires when an hour's spend runs more than 3x higher than your 7-day baseline and adds at least $5 of unexpected cost. You also get threshold alerts at 50%, 80%, and 100% of your budget, along with forecast projections based on the trailing 72 hours.

When an alert hits your Slack, Discord, or email, Pro and Team plans include an optional, reversible brake for Azure:

  • Turn off API keys: Sets disableLocalAuth to true on your Azure OpenAI or AI Services account when you click and confirm the brake. Once the change propagates, callers using an API key are refused while Microsoft Entra ID callers keep working.

Costbrake never takes destructive action or brakes on its own; an admin must explicitly confirm the action. Read-only setup takes a few minutes using a secretless Azure app registration that trusts Costbrake via federated credentials. Check our guide on how to monitor spend across OpenAI, Anthropic, Gemini and other AI APIs in one place or view the agent setup instructions to connect your environment.

Questions and answers

Can I set a hard spending limit on an Azure OpenAI resource?

No. Azure OpenAI does not offer native hard spending limits. Azure Cost Management budgets can trigger notifications or custom automation via action groups, but they will not halt API calls on their own.

How do I filter Azure OpenAI spend in the Azure portal?

Open Cost Management, select Cost Analysis, and apply a filter for Service tier: Azure OpenAI. It does not appear as its own entry in the top-level service list because Azure places it under the broader Cognitive Services classification.

How quickly does disabling local API key authentication take effect?

The control plane updates immediately, but the shared gateway cache can continue accepting valid keys for a few minutes up to several hours. Test the lockout by confirming requests return an HTTP 401 response stating access is denied due to an invalid subscription key.

Does Azure OpenAI bill for failed API requests?

HTTP error status codes alone don't determine whether a call is free. You are billed based on whether billable processing occurred before the error and the behavior of the specific meter.

How do I stop paying for fine-tuned models I am not using?

Fine-tuned models incur a continuous hourly hosting fee simply for remaining deployed, even with zero incoming requests. To stop the billing, delete or scale down the deployment in the portal when it is not actively serving traffic.

Sources

Updated