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 typeGranularityEnforcementUse case
Per-requestSingle API callHard limit via max_tokens parameterPrevent runaway completions, bound latency
Per-team quotaTeam or project over a periodSoft limit with alerts, hard limit at thresholdDepartmental cost allocation, prevent one team from consuming shared budget
Per-time-periodDaily, weekly, or monthlyHard limit with grace periodMonthly budget caps, sprint-level spending
Per-workflowSingle pipeline or agent runHard limit per step and totalMulti-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


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 →

Back to research

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.