Skip to main content
Version: Dev

Budgets

Budgets protect AI spend at the organization, environment, caller API key, provider key, team, member, or cost attribution tag level. The control plane counts spend and marks a budget exhausted when it reaches its limit. The gateway receives the budgets with its configuration and enforces them itself before calling an upstream provider.

Budgets are available with either AISIX Enterprise or AISIX Cloud. They are not part of the AISIX OSS resource model.

Prerequisites​

Before starting, prepare the following:

  • Access to the AISIX Enterprise or AISIX Cloud organization where you will create the budget.
  • For models that the catalog does not cover, configure Model Pricing so their traffic contributes spend to the budget.
  • For a team budget, create the team and bind the caller API keys whose traffic should count toward it.
  • For a tag budget, declare the tag key and set its values as described in Cost Attribution Tags.

Create a Budget​

  1. Open the Budgets view in the dashboard, then select New budget.
  2. Enter a Name for the budget.
  3. Select the Scope: organization, environment, caller API key, provider key, team, member, per member in a team, or tag. Then select the Environment or target when prompted. For a tag scope, select the tag key and enter the value. For a caller API key scope, select the Environment before selecting the API key.
  4. Enter the limit in Limit (USD) or, in a CNY organization, Limit (CNY), and select a day, week, or month Period. Budgets are in the organization's currency.
  5. In Alert thresholds (%), enter the percentages of the limit that should send notifications. The default threshold is 80%. See Budget Alerts and Notifications.
  6. Keep Hard stop at limit selected to reject matching traffic after the limit is reached. Clear it for a warn-only budget that keeps traffic flowing and surfaces the over-budget state in the control plane.
  7. Select Create budget.

Resource views also provide inline budget controls as shortcuts. These controls appear in the API key list, provider key list, Members view, and team detail page. The team detail page includes both the shared team budget and its per-member budget. An inline control and the Budgets view edit the same budget, so changes made in either location appear in both.

A target can hold one budget. Edit that budget to change its limit, period, or enforcement mode. Create another budget when you need to control a different target.

Budget Targets​

Choose the narrowest target that represents the spend you want to control:

TargetSpend counted toward the budget
OrganizationAll managed gateway traffic in the organization
EnvironmentTraffic in one deployment environment
Caller API keyTraffic authenticated with one downstream application or tenant key
Provider keyThe platform cost of models that use one upstream credential or provider account
TeamTraffic from every caller API key bound to one team
MemberTraffic from every caller API key bound to one member, across the organization
Each member in a teamA separate allowance for each member's traffic through keys bound to one team
TagTraffic attributed to one tag value, such as department=rnd, across every environment in the organization

Team and member budgets depend on the identity stored on the caller API key. A key can carry a team binding, a member binding, both, or neither. Team membership by itself does not make a key's spend count toward that team. Only the bindings on the key used for the request determine which budgets apply.

Provider-key accounting follows the credential attached to the model when the request's cost is counted. Enforcement follows the upstream a request would use, not the caller API key:

  • A routing target whose model uses a provider key with an exhausted blocking budget is skipped. AISIX removes it before it applies the routing strategy and the fallback limit, so a skipped target does not use up a fallback. A model group with targets on other provider keys keeps serving through them.
  • A request is rejected with 429 and budget_exceeded only when every target it could use is on an exhausted provider key, or when it calls a model that uses such a provider key directly.
  • In an ensemble model, a panel member on an exhausted provider key counts as a failed member, and a judge on one fails the request.

Provider-key budgets do not apply to MCP or A2A traffic.

A member budget and an each-member-in-a-team budget count different traffic:

  • A member budget is organization-wide. It combines spend from every caller API key bound to that member, regardless of the key's team binding.
  • An each-member-in-a-team budget gives every member a separate limit within one team. It applies only when the caller API key carries both that team binding and a member binding.

A tag budget counts every request whose resolved tags include its key=value pair, whichever of the caller API key, its team, or its member set the value. See How a Request Resolves Its Tags and Budget by Tag.

If a team or member budget counts unexpected traffic, inspect the bindings on the caller API key that reached the gateway, and check whether they changed during the current period. Spend counted before a binding change stays with the previous binding; see How Spend Is Counted.

Example: One Member in Two Teams​

Suppose Alice belongs to the frontend and data teams and uses three caller API keys:

KeyTeam bindingMember binding
K1frontendAlice
K2dataAlice
K3noneAlice

The organization configures these monthly budgets:

  • Alice has a $300 member budget. Spend from K1, K2, and K3 counts toward this organization-wide limit because all three keys are bound to Alice.
  • The frontend team has a shared $1,000 budget. Spend from every key bound to frontend counts, including K1 and keys bound to other members or to no member.
  • Each member in frontend has a $100 limit. Only K1 counts toward Alice's allowance because it carries both her member binding and the frontend team binding. Every other member gets an independent $100 allowance.

Traffic through K2 does not count toward either frontend budget. K3 does not count toward a team budget, even though Alice belongs to two teams, because the key has no team binding.

A request through K1 is checked against every matching budget. These include the frontend team budget, Alice's member budget, her frontend member allowance, and any matching organization, environment, or caller API key budget. Any matching blocking budget that has reached its limit rejects the request. A provider-key budget is checked against the upstream the request would use instead, as described above.

How Spend Is Counted​

The control plane counts spend incrementally. Within a few seconds after the gateway reports a request's usage, the request's cost is added to every budget it applies to. These include the matching organization, environment, caller API key, provider key, team, member, each-member-in-a-team, and tag budgets.

The cost added is the request's recorded cost, as Model Pricing describes: it reflects model-group prices, price tiers, and off-peak discounts, and a request answered from the response cache adds nothing.

A provider key budget is the exception. It accumulates what requests through the key cost you: each event's upstream_cost, falling back to cost_usd where that is null, because the target has no price or the event predates the field. So a model group's price and an off-peak discount do not change it, and a group priced at 0 still spends it. Every other scope accumulates cost_usd. A gateway needs no upgrade for this, because the control plane does the counting. Spend already counted does not drop when the control plane is upgraded, but a provider key budget in an environment that uses group prices then grows at a different rate, so it can reach a hard limit at a different time.

A request is attributed when its cost is counted. Attribution uses the bindings in effect at that moment: the caller API key's team and member bindings, the model's provider key, and the environment's organization. Tag budgets are the exception: they count the tags the gateway recorded on the request's usage when it ran, so a later tag change never moves spend that was already recorded. Spend already counted stays where it was counted. The following changes leave the current period's counted spend unchanged, and only later requests follow the new bindings:

  • Rebinding a caller API key to another team or member.
  • Moving a model to another provider key.
  • Deleting a caller API key, member, team, or environment.
  • Removing usage records older than the organization's usage data retention window.

For example, after a key moves from the frontend team to the data team, the spend from its earlier requests remains in the frontend team budget. The key's later requests count toward the data team budget and are no longer checked against the frontend budget.

A new budget does not start from zero. When you create a budget, or change its target or period, it starts from the spend already recorded for its target in the current period, attributed under the current bindings. After that, it counts new spend incrementally.

Each period starts from zero. Usage reported late for a request that occurred in the previous period is not counted.

Enforcement Path​

Applications continue to use the same proxy API and caller API key after a budget is configured. They do not call a separate budget API.

The control plane sends every blocking budget to the gateways of each environment it applies to, as part of their configuration, and marks a budget exhausted once its spend reaches the limit. Warn-only budgets are not sent. Before AISIX sends a provider request, the gateway checks the budgets it holds. It does not ask the control plane, so a request that no blocking budget applies to never depends on the control plane for its budget check.

If no matching blocking budget is exhausted, the request follows the normal proxy path. Usage from that request can put a budget over its limit after the provider responds. Within a few seconds, the control plane counts that spend and marks the budget exhausted, and the gateway then rejects matching traffic before the provider call. Raising the limit above the spend, clearing Hard stop at limit, or deleting the budget lifts the block the same way.

The gateway also lifts an exhausted budget on its own when the next period starts. Periods follow the UTC calendar: a day starts at 00:00 UTC, a week on Monday at 00:00 UTC, and a month on the 1st at 00:00 UTC. A budget with a limit of zero rejects matching traffic in every period.

Budget Rejection Response​

For OpenAI-compatible requests, a budget rejection returns 429 with an OpenAI-style error envelope:

{
"error": {
"message": "api key budget 'production-chat' exceeded ($1.00/month). Resets 2026-06-01 00:00 UTC.",
"type": "billing_error",
"code": "budget_exceeded",
"scope": "api_key",
"scope_ref": "api-key-uuid-1",
"limit_usd": "1.00",
"spent_usd": "2.00",
"period": "month",
"period_resets_at": "2026-06-01T00:00:00Z",
"retry_after_seconds": 259200
}
}

The amounts are in the organization's currency. message writes the limit with that currency's symbol, such as ¥1.00 in a CNY organization, while limit_usd and spent_usd keep their names and carry plain numbers in that currency.

Anthropic-compatible Messages requests keep the Anthropic error format and do not include the additional budget fields.

Behavior During a Control-Plane Outage​

Budget checks run on the gateway. With the default Keep last known state mode, a control-plane outage does not by itself cause budget rejections. While the control plane is unreachable, the gateway keeps enforcing the budgets it last received:

  • A budget that was exhausted stays enforced. The gateway lifts it when the next period starts, without waiting for the control plane.
  • A budget that was not exhausted keeps admitting traffic. Spend is counted from the usage that gateways report, so while a gateway cannot report usage, the control plane cannot mark the budget exhausted, and traffic can exceed the limit.
  • A request that no blocking budget applies to is unaffected.

The budgets travel with the gateway's configuration. A gateway that restarts during the outage and recovers from its configuration cache keeps enforcing them.

Choose the Budget Enforcement Mode​

The organization's budget enforcement mode decides what the gateway does with budgeted traffic while it cannot report usage. To change it, open Settings and find the Budget enforcement card. Only organization owners and admins can change it.

ModeBehavior while a gateway cannot report usage
Keep last known state (recommended)The default. The gateway keeps enforcing the last budget state it received, as described above.
StrictAfter the gateway has been unable to report usage for the grace period, it rejects requests from caller API keys that a blocking budget applies to with 503 and the code budget_unverified, and it stops using upstreams whose provider key has a blocking budget. Requests and upstreams that no blocking budget applies to are unaffected.

Strict mode trades availability for a firmer spending cap. An organization or environment budget applies to every caller API key, so in strict mode it rejects all traffic in its environment once the grace period has passed.

Set the grace period in Strict-mode grace period (seconds) on the same card, then select Save. It defaults to 600 seconds and accepts whole numbers from 60 to 86400.

The grace period starts when the gateway has usage waiting that it cannot deliver. A successful delivery, or a delivery rejected with 422 for its content, ends the timer and stops strict-mode rejections. A connection failure, timeout, server error, or authorization refusal does not end it. Each gateway measures its own delivery, and reports how long it has been failing in aisix_usage_delivery_unhealthy_seconds.

In strict mode, a budget that is already exhausted is still rejected with 429 and budget_exceeded. When a model group's targets are all excluded, the request receives 429 budget_exceeded if any of them is on an exhausted provider key, and 503 budget_unverified otherwise.

The fail-open mode of earlier releases is no longer available. An organization that used it was switched to Keep last known state when the control plane was upgraded.

Budget Usage Metrics​

The control plane tracks budget usage from managed gateway traffic. When a budget rejects a caller API key, AISIX records budget gauges from that budget's totals with the caller API key ID and, when available, the projected team and member IDs. When a later request from that key is not rejected by a budget, AISIX sets aisix_budget_details_present to 0 for that key identity but retains the last reported amounts. Ignore those amounts unless the presence flag is 1. The aisix_budget_limit_usd, aisix_budget_spent_usd, and aisix_budget_remaining_usd gauges carry the amounts the control plane reports, so they are in the organization's currency despite their names. After the organization switches currency, a series continues with numbers in the new currency.

Verify Budget Enforcement​

Send traffic with a caller API key and model that match the budget target. Then check the budget in the Budgets view and confirm that spend is counted against the expected scope.

Until the control plane measures a budget's spend for the first time, the budget shows no spend data yet instead of $0.00. A new budget normally gets its first measurement within a few seconds, and after a control-plane upgrade every budget waits for the next measurement. The same applies to the budget section on the caller API key, environment, team, member, and provider key pages. In the Admin API, state.aggregated_at is null until that first measurement and then records when spend was last measured.

Use Usage Reporting to confirm that the model requests produce spend. If token usage appears without spend, check that Model Pricing contains an exact provider and model-name match.

A warn-only budget continues to allow matching traffic after the limit is reached and shows the over-budget state in the control plane. A blocking budget rejects a later matching request with 429. The request that crosses the limit can still complete because the control plane records its usage after the provider responds. Requests sent in the few seconds before the gateway receives the exhausted budget can also complete.

Review Budget Rejections​

When AISIX Enterprise or AISIX Cloud returns budget_exceeded, inspect the error code and structured budget fields first. The gateway made the decision from the budget state the control plane last sent it; the denial did not come from the AISIX Cloud Admin API.

A 503 with the code budget_unverified is not a spending decision. It means the organization uses strict budget enforcement and the gateway has been unable to report usage for longer than the grace period. Check the gateway's connectivity to the control plane and its aisix_usage_delivery_unhealthy_seconds metric; see Behavior During a Control-Plane Outage.

Find the returned target in the Budgets view and review its limit, period, and enforcement mode. If the scope is unexpected, inspect the team and member bindings on the caller API key used for the request.

Next Steps​

Configure Budget Alerts and Notifications to receive a webhook or Slack message when a configured threshold is reached. Then use Logging and Auditing to investigate budget rejections and the control-plane changes behind them.