A quota that is too loose lets a looping agent burn through tokens, tool calls and downstream APIs, and a quota that is too tight kills legitimate long-running work halfway through. This guide is about the design of the limits themselves: which units to meter, how to key them on task, tool and identity, how to size them from real baselines, and what an agent should do when it hits one. It is written for platform, AI engineering and security teams who build or operate agents in production. Cost risk, budgets and billing alerts are covered in the Denial-of-Wallet and AI Agent Cost Runaway Guide.
Key takeaways
- Meter three scopes, not one. A per-task budget stops loops, a per-tool limit stops damage at the point of action, and a per-identity quota stops one agent or tenant starving everyone else.
- Pick the unit that matches the harm. Turns and steps catch loops, tokens catch context growth, tool calls catch side effects, and concurrency catches fan-out. A request count alone catches none of them well.
- Size limits from observed percentiles. Set the per-task ceiling at a multiple of the p99 of successful runs, then tighten it as the baseline settles, rather than guessing a round number.
- Design the stop, not just the limit. An agent that hits a quota should checkpoint, return a controlled result and escalate, not crash, retry blindly or lose its work.
- Treat quota changes as privileged actions. In the Sourcegraph incident an attacker with a leaked admin token raised rate limits for their own proxy users, so the ability to change a limit needs the same protection as the credential it limits.
Why agents need different quota design
Classic API rate limiting assumes independent requests of similar size. Agents break both assumptions: one user request becomes dozens of model calls, each larger than the last as history is resent, a planner can spawn sub-agents per item, and a failing tool can be retried by the SDK, the framework and the model at once. The dangerous part is often the tool call, not the model call: an email sent, a record deleted, a payment initiated.
OWASP LLM10:2025 Unbounded Consumption recommends rate limiting, user quotas and limits on queued actions. LLM06:2025 Excessive Agency notes that rate limiting the interface an agent acts through, such as a mail-sending tool, reduces damage from a hijacked agent. API4:2023 Unrestricted Resource Consumption adds timeouts, operations per request and third-party spending limits. Agent quota design has to cover all three.
See the OWASP LLM Top 10 LLM10 Unbounded Consumption Guide for the risk itself and the Rate Limiting and API Abuse Guide for limits on public APIs.
The three scopes: task, tool and identity
| Scope | Question it answers | Typical units | What it stops | Where it is enforced |
|---|---|---|---|---|
| Per task (per run) | Is this one piece of work still making progress? | Turns, graph steps, tokens, tool calls, wall-clock seconds | Loops, oscillation between two tools, runaway reasoning, context explosion | Agent framework and orchestrator |
| Per tool | Is this action happening at a safe rate? | Calls per minute, items affected, value moved, distinct recipients | Mass deletion, bulk email, spend, scraping, injected instructions acting at scale | Tool wrapper, MCP server or the downstream API |
| Per identity | Is this agent, user or tenant taking more than its share? | Tokens per minute and per day, concurrency, requests per second | Fan-out, a bad release, a stolen agent credential, noisy neighbours | AI gateway or API gateway keyed on the caller |
| Shared backstop | Is the whole platform within capacity and budget? | Provider rate limits, project spend limits | Everything the layers above miss, including gateway bypass | Model provider and cloud account |
The scopes nest: a per-task ceiling sits well below the per-identity quota, and per-identity quotas together sit below the provider limit. AWS applies the same principle in API Gateway, where per-client usage plan limits cannot exceed per-account limits.
Per-task budgets
A task budget is a set of counters created when a run starts and discarded when it ends. Track at least four:
- Steps or turns: the number of model calls or graph steps. This is the cheapest and most reliable loop breaker.
- Tokens: input plus output across the run. This catches a run that makes few calls but resends an ever-larger context.
- Tool calls: total, and per tool. A research agent that has called the search tool 200 times is lost, whatever its token count says.
- Wall-clock time: a deadline for the whole run, which also bounds waits on slow tools.
Add a repetition check: the same tool called with the same arguments three times in a row, or two tools alternating without new information, is a loop even while every counter is green.
Per-tool limits
Tool limits matter most for harm. Set them on the action, in units of consequence:
- Rate: calls per minute per agent identity, for example email sends or ticket updates.
- Blast radius per call: maximum records affected, recipients or rows returned. Reject a delete matching 10,000 rows even on the first call of the day.
- Cumulative value: money moved, credits issued or refunds granted per run and per day. Above a threshold the call should route to approval. See the AI Agent Action Approvals and Spending Limits Guide.
- Downstream cost: paid third-party APIs such as SMS, search or enrichment, which never show up in token counters.
Enforce tool limits in the tool wrapper or MCP server so a prompt-injected agent cannot talk past them; a limit stated in the system prompt is guidance, not a control. See Tool-Call Security for AI Agents.
Per-identity quotas
If ten agents share one API key, the quota protects the key, and one runaway agent takes the other nine down. Key the counter on the agent's workload identity, with the end user or tenant as a second key where the agent acts on someone's behalf. See Shared credentials between AI agents and the Agent Identity and Access Guide.
Choosing the algorithm and the unit
Agents are bursty: planning is quiet, fan-out is loud. Choose an algorithm that absorbs short legitimate bursts but not sustained abuse.
| Algorithm | How it behaves | Good for | Watch out for |
|---|---|---|---|
| Token bucket | Tokens refill at a steady rate up to a bucket size; a request spends tokens and is rejected when the bucket is empty | Per-identity rate limits that allow short bursts; used by AWS API Gateway (rate and burst) and the Envoy local rate limit filter (max_tokens, tokens_per_fill, fill_interval) | A large bucket lets a fan-out spend a minute's allowance in one second |
| Fixed window quota | A counter resets at a fixed boundary (hour, day, month) | Daily or monthly token allowances per agent or tenant; Azure API Management token-quota-period uses fixed periods truncated to UTC | Double spending across the boundary; a full day's quota can be spent in minutes |
| Concurrency limit | Caps in-flight requests or runs, not their rate | Fan-out and long-running tool calls | Needs reliable release on timeout or crash, or slots leak |
| Run counter | Simple increment per step, per tool call, per token within one run | Per-task budgets | Must survive retries and resumes, or a restarted run gets a fresh budget |
Combine a token bucket for rate with a fixed window for volume: the bucket stops bursts, the daily quota stops slow leaks.
Meter tokens before the call where you can. With Azure API Management's llm-token-limit, estimate-prompt-tokens set to false lets the prompt reach the model before the limit is detected, and because exact usage is known only after the response, concurrent requests can briefly overshoot. Leave margin for it.
Know where the counter lives. That policy counts independently at each gateway, and the Envoy local filter counts per Envoy process by default, so 1,000 tokens per minute on five instances can mean 5,000. Use a shared counter store for limits that must be global.
Framework and gateway controls you can use
Frameworks and gateways are listed alphabetically; order is not a ranking. Each row gives the setting as named in the project's own documentation, checked in November 2026. Defaults change between releases, so confirm them against the version you run.
| Component | Setting | Scope | Behaviour on breach |
|---|---|---|---|
| AutoGen AgentChat | MaxMessageTermination, TokenUsageTermination, TimeoutTermination, ExternalTermination; combine with | (any) or & (all) | Per task | The team run stops; ExternalTermination lets your code stop a run from outside |
| AWS API Gateway | Usage plan throttle (rateLimit, burstLimit) and quota per API key; stage and method throttles | Per identity and per route | HTTP 429; AWS states throttles and quotas are best-effort targets, not guaranteed ceilings |
| Azure API Management | llm-token-limit with counter-key, tokens-per-minute, token-quota and token-quota-period | Per identity (any key expression) | HTTP 429 for the per-minute rate, HTTP 403 for the quota |
| CrewAI | max_iter (default 20), max_rpm, max_execution_time, max_retry_limit (default 2) | Per agent and per task | The agent must give its best answer at max_iter |
| Envoy | Local rate limit filter token bucket with descriptors; optional enable_retry_after_header | Per route or descriptor | HTTP 429 by default with x-envoy-ratelimited |
| LangGraph | recursion_limit as a top-level config key, or LANGGRAPH_DEFAULT_RECURSION_LIMIT | Per task (super-steps) | GraphRecursionError; the default is 10,007 super-steps from version 1.1.4 |
| OpenAI Agents SDK | max_turns on the run; error_handlers={"max_turns": ...} | Per task (model calls) | MaxTurnsExceeded, or a controlled final_output from the handler |
A default of over 10,000 super-steps is a safety net against infinite recursion, not a business limit. For every framework, the setting exists but the number is yours to choose.
Sizing limits without breaking workflows
Fear of breaking real work is why limits get set too high or not at all. Size them from data. The sizing method below, including the multipliers, is an NHI Mgmt Group recommendation, not a published standard.
- Instrument first. Log steps, tokens, tool calls and duration per run, tagged with agent, task type and outcome, for two to four weeks without enforcement.
- Segment by task type. A code-migration agent and a triage agent have different shapes; one limit fits neither.
- Use percentiles of successful runs. Take the p99 of steps, tokens and tool calls for runs that completed correctly, and set the hard ceiling at two to three times that value. Set a soft threshold at the p99 itself, which alerts or asks for approval but does not stop.
- Check the outliers. If runs above p99 were mostly loops or errors, the ceiling is right; if many were legitimate large jobs, give them their own task type and budget rather than raising the limit for everyone.
- Set per-identity quotas from peak, not average, keeping their sum below the provider limit with a reserve for incident response.
- Review quarterly and on model changes, which alter token and step counts.
Our recommendation: small teams can start with a per-task cap of a few dozen steps, a rate on every tool that writes or sends, and one quota per agent key, then refine. Large organisations should hold limits as version-controlled configuration owned by each agent's business owner, with platform defaults where none is set.
Designing what happens at the limit
A limit that crashes the run throws away work and invites the operator to raise it. A good stop keeps the work and hands control to someone who can decide.
| Limit hit | Agent behaviour | Retry? | Escalation |
|---|---|---|---|
Per-identity rate (HTTP 429 with Retry-After) | Wait the stated time with jitter, then resume | Yes, within a retry budget | Alert if sustained |
| Per-identity quota exhausted (daily or monthly) | Checkpoint state, return a clear "quota exhausted" result | No, until the window resets or an owner raises it | Notify the agent owner |
| Per-task step, token or time ceiling | Stop, save progress and summary, return a controlled partial result | No automatic retry | Human review of the run; resume with a new, approved budget if justified |
| Per-tool rate or blast-radius limit | Refuse the call, tell the model why, continue with other work if possible | No | Approval request for the blocked action |
| Repetition or loop detected | Stop the run | No | Flag as a probable defect or hijack |
| Provider spend limit | Fail fast across all agents in the project | No | Incident: page the platform owner |
Retry budgets: Google's SRE guidance caps each request at three attempts and allows retries only while a client's retry ratio stays below 10 percent, keeping retry growth near 1.1 times instead of nearly three. For agents: one retry layer only, a per-run retry count, and no retry on quota or spend errors.
Tell the client the state: return remaining quota so agents slow down before they are cut off. The IETF RateLimit header fields draft (draft-ietf-httpapi-ratelimit-headers-11, Internet-Draft dated 23 May 2026, subject to change) defines RateLimit-Policy (quota q, window w, partition key pk) and RateLimit (remaining r, window t), recommends HTTP 429 for quota exceeded, gives Retry-After precedence, and advises jitter so throttled clients do not retry together.
Make the stop resumable: persist run state at each step so a halted run can resume after review, carrying its consumed counters forward rather than getting a fresh budget.
Where identity fits
Quotas are only as good as the identity they are keyed on.
- Distinct identity per agent: one credential per agent instance or agent family gives you a counter per agent and lets you revoke one without stopping the rest. See the AI Agent Credential Lifecycle and Rotation Guide.
- Keys are not authentication: AWS uses API keys in usage plans to identify clients for throttling, and they can be shared or leaked. Authenticate the agent with a workload identity, then use the verified identity as the counter key.
- Protect the limit itself: whoever can change a quota can disable it. In the Sourcegraph breach, an attacker using a leaked site-admin token granted higher rate limits to users of their LLM proxy. Put quota configuration behind privileged access and change approval, and alert on every change.
Detection and measurement
Quota events are detection signals: a run that hits its ceiling is a defect, a model change or a hijack. Log limit hits by scope, repetition detections, soft threshold crossings and every quota configuration change (who, from what, to what, approved by whom), tagged with agent identity, task type and tool.
Metrics that show the design is working:
- Agent coverage: share of production agents with all three scopes limited. Target 100 percent.
- False stop rate: share of ceiling hits that were legitimate work; a high rate means re-size, not remove.
- Time to stop a runaway: from loop start to automatic halt, measured in exercises. Minutes, not hours.
- Retry amplification: total calls divided by logical calls; well above 1.1 means stacked retries.
- Quota headroom: peak usage as a share of identity quotas and provider limits.
See the Rogue and Runaway AI Agent Detection Guide and the AI Agent Behaviour Baselining and Anomaly Detection Guide for the wider detection picture.
How to implement
- Inventory agents, identities and write tools, and split shared keys so each agent has its own counter key.
- Turn on framework run limits. Set an explicit turn, step or iteration limit and a run timeout in every agent, replacing defaults that are disabled or very high.
- Add per-tool limits on write tools. Start with rate and blast radius on email, deletion, payment and permission-changing tools, enforced in the tool layer.
- Put per-identity quotas at the gateway in audit mode. Log what would have been blocked for two weeks, then compare with the baseline.
- Enforce in rings: internal and low-risk agents first, then customer-facing ones, watching false stop rate.
- Wire the stop behaviour. Checkpoint on limit, controlled partial results, approval routing for blocked tool calls, and one retry layer.
- Plan rollback: keep the previous limit set deployable in one step and use time-boxed, approved overrides for a named agent, never a global increase or a disabled limit.
Framework mapping
| Framework | Reference | How quota design applies |
|---|---|---|
| OWASP Top 10 for LLM Applications 2025 | LLM10 Unbounded Consumption; LLM06 Excessive Agency | Rate limiting and user quotas; limiting queued actions; rate limiting the interfaces an agent acts through |
| OWASP API Security Top 10 2023 | API4:2023 Unrestricted Resource Consumption | Timeouts, operations per request and third-party spending limits on tools and APIs agents call |
| MITRE ATLAS | AML.T0034 Cost Harvesting; AML.T0029 Denial of AI Service | Per-identity quotas and per-task budgets limit what an attacker can consume or disrupt |
| NIST SP 800-53 Rev. 5 | SC-5 Denial-of-service Protection; SC-6 Resource Availability; AC-6 Least Privilege; SI-4 System Monitoring; AU-6 Audit Record Review | Quotas allocate resources by priority; per-tool limits restrict what an agent can do; limit hits feed monitoring and review |
| NIST CSF 2.0 | PR.IR-04; DE.CM-09; RS.MI-01 | Capacity maintained for availability; runtime monitored for adverse events; automatic stops as containment |
Common failure patterns
- One shared key, one quota. Every agent shares a provider key, so the first runaway agent exhausts the limit and the rest fail with it.
- Trusting framework defaults. A turn limit left very high, or disabled with
None, misses loops a few dozen steps would catch. - Stacked retries. SDK, framework and application all retry, turning one failing call into dozens, including retries on quota errors that cannot succeed.
Practitioner checklist
- Every production agent has an explicit per-task step or turn limit, token budget and run timeout.
- Every tool that writes, sends, spends or deletes has a rate limit and a blast-radius limit enforced in the tool layer.
- Each agent has its own identity, and gateway quotas are keyed on that verified identity, plus user or tenant where relevant.
- Limits are sized from p99 of successful runs per task type, with soft and hard thresholds.
- Hitting a limit checkpoints the run and returns a controlled result; quota and spend errors are never retried.
- Only one layer retries, with a per-run retry budget and jittered backoff.
- Quota configuration is version-controlled, changes need approval, and every change raises an alert.
Standards and references
- OWASP: Top 10 for LLM Applications 2025
- OWASP: API Security Top 10 2023
- IETF: RateLimit header fields for HTTP (Internet-Draft)
- NIST: SP 800-53 Rev. 5
- MITRE ATLAS: Cost Harvesting
- Google: Site Reliability Engineering, Handling Overload
- AWS: Throttle requests to your REST APIs in API Gateway
- Microsoft Learn: Limit large language model API token usage
Related NHI Mgmt Group resources: Denial-of-Wallet and AI Agent Cost Runaway Guide · AI Agent Kill Switch and Containment Guide · Agent Controls and Monitoring Guide · Human-in-the-Loop for AI Agents Guide