Token budget implementation guide
Updated 12 July 2026 · first published 4 July 2026
Token budgets are the operational layer of LLM cost control. Attribution tells you where money goes; budgets prevent it from going places you do not want. Without budgets, a single misconfigured agent loop or a spike in user traffic can blow through a monthly allocation in hours. This guide covers how to implement four types of token budgets in production, with pseudocode for each pattern.
Budget types
| Budget type | Granularity | Enforcement | Use case |
|---|---|---|---|
| Per-request | Single API call | Hard limit via max_tokens parameter | Prevent runaway completions, bound latency |
| Per-team quota | Team or project over a period | Soft limit with alerts, hard limit at threshold | Departmental cost allocation, prevent one team from consuming shared budget |
| Per-time-period | Daily, weekly, or monthly | Hard limit with grace period | Monthly budget caps, sprint-level spending |
| Per-workflow | Single pipeline or agent run | Hard limit per step and total | Multi-step agents, RAG pipelines, eval runs |
Per-request limits
The simplest budget: cap every request with max_tokens. This is not optional - every production request should have an explicit output token limit. Without it, a verbose model response can consume unexpected tokens and inflate latency.
// Per-request budget enforcement
function callLLM(prompt, config):
response = provider.complete(
prompt: prompt,
model: config.model,
max_tokens: config.max_output_tokens, // hard cap
temperature: config.temperature
)
if response.usage.total_tokens > config.warn_threshold:
log.warn("Request exceeded soft limit",
tokens: response.usage.total_tokens,
threshold: config.warn_threshold
)
return response
Per-team quotas
Team quotas require a shared counter that persists across requests. The pattern: check remaining budget before each call, reject or downgrade if the budget is exhausted.
// Team quota with Redis-backed counter
function checkTeamBudget(teamId, estimatedTokens):
key = "budget:" + teamId + ":" + currentPeriod()
remaining = redis.get(key) or getTeamQuota(teamId)
if remaining < estimatedTokens:
if remaining < estimatedTokens * 0.1:
return DENY // hard limit: reject request
else:
return DOWNGRADE // soft limit: use cheaper model
return ALLOW
function recordUsage(teamId, actualTokens):
key = "budget:" + teamId + ":" + currentPeriod()
redis.decrby(key, actualTokens)
remaining = redis.get(key)
if remaining < getTeamQuota(teamId) * 0.2:
alert.quotaLow(teamId, remaining)
Per-time-period budgets
Time-period budgets wrap team quotas with a time window. The key difference: you need a grace period mechanism. When a team hits 80% of their monthly budget, send an alert. At 100%, allow a configurable grace period (e.g., 24 hours) before hard enforcement kicks in. This prevents a team from being blocked mid-task on the last day of the month.
// Time-period budget with grace period
function enforceBudget(teamId):
usage = getUsageForPeriod(teamId, currentMonth())
limit = getTeamMonthlyLimit(teamId)
if usage < limit * 0.8:
return ALLOW
if usage < limit * 1.0:
alert.budgetWarning(teamId, usage, limit)
return ALLOW // soft warning zone
if usage < limit * 1.1 and withinGracePeriod(teamId):
alert.budgetExceeded(teamId, usage, limit)
return ALLOW // grace period: allow overage
return DENY // hard stop
Per-workflow budgets
Multi-step agents and pipelines need budgets at two levels: per-step (prevent any single step from consuming too much) and per-run (prevent the entire pipeline from exceeding its allocation). Track both in the workflow context.
// Workflow budget tracker
class WorkflowBudget:
constructor(maxPerStep, maxTotal):
this.maxPerStep = maxPerStep
this.maxTotal = maxTotal
this.spent = 0
function callStep(stepFn, prompt):
if this.spent >= this.maxTotal:
return fallbackResponse("Budget exceeded")
response = callLLM(prompt, {
max_tokens: min(this.maxPerStep,
this.maxTotal - this.spent)
})
this.spent += response.usage.total_tokens
return response
Graceful degradation when budget is exceeded
Do not just return an error when a budget is hit. Downgrade gracefully. Switch to a cheaper model (GPT-4o-mini instead of GPT-4o), reduce context window size, skip optional processing steps, or return a partial result with a note that full processing requires budget approval. The user experience should degrade, not break.
// Degradation chain
function callWithDegradation(prompt, config):
if checkBudget(config.teamId, FULL_MODEL):
return callLLM(prompt, { model: config.primaryModel })
if checkBudget(config.teamId, CHEAP_MODEL):
log.info("Downgrading model for budget")
return callLLM(prompt, { model: config.fallbackModel })
if checkBudget(config.teamId, MINIMAL_TOKENS):
truncated = truncateContext(prompt, 50%)
return callLLM(truncated, {
model: config.fallbackModel,
max_tokens: 256
})
return cachedOrFallback(prompt)
Monitoring budget health
Track three metrics: burn rate (tokens consumed per hour vs. budget), forecast (at current rate, when will the budget be exhausted), and override count (how many times the grace period was used). If grace period usage exceeds 10% of total requests, the budget is set too low for the workload.
Related
- LLM budget governance - organizational policies behind budgets.
- Agent spend guardrails - budget patterns for autonomous agents.
- How to cap inference costs - provider-side cost controls.
Want this applied to your own LLM spend? FinOps LLM runs a free audit of your AI costs and shows where the savings are. Book free audit →
FAQ
What are the four types of token budgets?
The four budget types are: (1) Per-request - single API call with hard limit via max_tokens parameter to prevent runaway completions; (2) Per-team quota - team or project over a period with soft limit and hard threshold to prevent one team from consuming shared budget; (3) Per-time-period - daily, weekly, or monthly with hard limit and grace period for monthly budget caps; (4) Per-workflow - single pipeline or agent run with hard limit per step and total to control multi-step agents and RAG pipelines.
What is the simplest token budget to implement?
The simplest budget is per-request: cap every request with max_tokens. This is not optional—every production request should have an explicit output token limit. Without it, a verbose model response can consume unexpected tokens and inflate latency.
How should per-team quotas be enforced?
Team quotas require a shared counter that persists across requests. The pattern: check remaining budget before each call, reject or downgrade if the budget is exhausted. Use a soft limit to trigger a downgrade to a cheaper model, and a hard limit to reject the request outright. Record actual usage and alert when remaining budget falls below a threshold.
What is the purpose of a grace period in time-period budgets?
A grace period mechanism prevents a team from being blocked mid-task on the last day of the month. When a team hits 80% of their monthly budget, send an alert. At 100%, allow a configurable grace period (e.g., 24 hours) before hard enforcement kicks in. This gives teams time to wrap up important work.
How should multi-step agent budgets be tracked?
Multi-step agents and pipelines need budgets at two levels: per-step (prevent any single step from consuming too much) and per-run (prevent the entire pipeline from exceeding its allocation). Track both in the workflow context, ensuring that each step respects both its own limit and the remaining total-run budget.
What is graceful degradation in token budget enforcement?
Do not just return an error when a budget is hit. Downgrade gracefully. Switch to a cheaper model, reduce context window size, skip optional processing steps, or return a partial result with a note that full processing requires budget approval. The user experience should degrade, not break.