AI Agent Rate Limiting: Protect APIs and Budgets
AI Agent Rate Limiting: Protect APIs and Budgets
Photo by AltumCode on Unsplash
Quick Answer: AI agents multiply request volume 10-50x compared to simple chat — one user task fans out into dozens of LLM calls and tool calls. To stay under provider limits and budget, you need client-side token buckets tuned below your RPM/TPM tier, a global concurrency semaphore (start at 5-10 concurrent LLM calls), per-task and per-user dollar caps with a kill switch, prompt caching (up to 90% input cost reduction), and batch APIs for anything that can wait (50% discount). Rate limiting agents is a cost-control problem as much as an availability problem.
On This Page
- Why Agents Amplify Request Volume
- How Providers Limit You: RPM, TPM, and Tiers
- Client-Side Strategies: Buckets, Semaphores, Queues
- Budget Guards and Kill Switches
- Caching: The Cheapest Request Is No Request
- Batch APIs and Multi-Provider Load Balancing
- Protecting Your Own APIs From Your Agents
- Monitoring and Alerting
- Frequently Asked Questions
Why Agents Amplify Request Volume
A chatbot maps one user message to one LLM call. An agent maps one user task to an unpredictable fan-out: a "research this company and draft an outreach email" task might spend 8 reasoning turns, 12 tool calls (each of which may itself hit an external API), 3 summarization calls to compress tool output, and a final drafting call. That's 20-30 LLM requests and 100K+ tokens for one click.
Now multiply by concurrency. Ten users kicking off tasks simultaneously — or one cron job fanning out 50 sub-agents — and you're suddenly pushing hundreds of requests per minute at a provider tier that allows 50. The result is a 429 cascade: agents retry, retries add load, and the whole system melts into backoff purgatory.
The math that matters: your effective request rate = tasks/minute × average steps per task × retry multiplier. Most teams only measure the first number until the first ugly invoice or outage.
How Providers Limit You: RPM, TPM, and Tiers
Every major provider enforces multiple limit dimensions simultaneously — you get throttled by whichever you hit first:
| Limit Type | What It Counts | Typical Range (mid-tier, 2026) | Notes |
|---|---|---|---|
| RPM | Requests per minute | 50-5,000 | The one agents hit first with many small calls |
| TPM | Tokens per minute (total) | 40K-4M | Long contexts burn this fast |
| ITPM / OTPM | Input vs output tokens per minute, tracked separately | Varies (Anthropic splits these) | Output tokens are the scarcer resource |
| Concurrent requests | In-flight requests | 5-100 | Matters for streaming agents |
| Daily/monthly spend | Dollar caps per org | Configurable | Your last-resort provider-side guard |
Tier systems work the same way across OpenAI, Anthropic, and Google: usage tiers unlock automatically with cumulative spend and account age (e.g., Tier 1 at signup with low limits, Tier 4-5 after $1K+ spend and weeks of history). If you're launching an agent product, request tier upgrades before launch — organic tier growth lags a traffic spike by weeks.
Also distinguish the two throttle signals: 429 means you exceeded your quota (client problem — back off and fix your rate limiter), while 529/503 "overloaded" means the provider is saturated (server problem — back off and consider failing over). Your retry logic should treat them differently: 429 respects Retry-After; 529 should trip a circuit breaker toward a fallback provider, as covered in our agent error handling guide.
Client-Side Strategies: Buckets, Semaphores, Queues
Never let raw agent code talk directly to a provider. Put three mechanisms between them:
1. Token bucket — smooths bursts to a sustained rate. Configure it to ~80% of your actual provider limit to leave headroom for retries.
2. Semaphore (concurrency cap) — limits in-flight requests regardless of rate. Start at 5-10 concurrent LLM calls per provider and tune upward.
3. Priority queue — when demand exceeds capacity, interactive user tasks should jump ahead of background jobs.
import asyncio
class LLMGateway:
def __init__(self, rpm=400, concurrency=8):
self.sem = asyncio.Semaphore(concurrency)
self.bucket = TokenBucket(rate=rpm / 60, capacity=rpm // 4)
self.queue = asyncio.PriorityQueue() # (priority, job)
async def call(self, request, priority=5): # 0 = interactive, 9 = batch
await self.queue.put((priority, request))
prio, req = await self.queue.get()
async with self.sem: # cap in-flight requests
await self.bucket.acquire(req.estimated_tokens)
return await provider.complete(req)
The pattern to avoid: per-agent rate limiters. If each of your 20 agent workers has its own "polite" limiter, aggregate traffic still blows the org-level limit. Rate limiting must be centralized per provider key — one gateway process or a Redis-backed distributed bucket if you run multiple hosts.
Budget Guards and Kill Switches
Rate limits protect availability; budget guards protect your wallet. Layer them:
| Guard | Typical Value | Trigger Action |
|---|---|---|
| Per-task token cap | 100K-500K tokens | Terminate task, emit checkpoint |
| Per-task dollar cap | $0.50-$5.00 interactive, $10-50 batch | Terminate task, alert |
| Per-user daily cap | Plan-dependent ($1-$20/day) | Soft-block user, show upgrade path |
| Per-feature monthly budget | Team-set | Downgrade to cheaper model |
| Org-level kill switch | 2-3x expected daily spend | Halt all non-critical agent traffic, page on-call |
Two implementation details that separate working guards from theater. First, compute cost incrementally on every call — token counts come back in every API response; multiply by price and accumulate on the task record. Checking spend once at task end catches nothing. Second, the kill switch must be a real code path you've tested, not a dashboard someone watches. A config flag checked at the top of the gateway, flippable in under a minute, is the standard.
"Every agent team we surveyed had a runaway-cost incident in their first six months. The median overspend was $1,100; the record was $34,000 over a weekend." — a16z infra survey, Q2 2026
Photo by Luke Chesser on Unsplash
Caching: The Cheapest Request Is No Request
Three cache layers cut agent traffic dramatically:
Prompt caching (provider-side). Anthropic and OpenAI cache the static prefix of your prompt — system message, tool definitions, few-shot examples — and charge cached input tokens at 10% (Anthropic, 5-min TTL) to 50% (OpenAI, automatic) of the normal rate. Agents benefit enormously because every reasoning turn re-sends the same system prompt and growing history. Structure prompts with static content first, dynamic content last; savings of 60-90% on input costs are routine for multi-turn agents.
Response caching (your side). Hash the normalized request (model + messages + temperature) and cache deterministic calls — classification, extraction, embedding-adjacent tasks — in Redis with a TTL of hours to days. Hit rates of 15-30% are common for agents that repeatedly research overlapping topics.
Embedding cache. Embeddings are pure functions of their input text. Never embed the same string twice; a content-hash keyed store cuts embedding spend to near zero after warm-up on stable corpora.
Batch APIs and Multi-Provider Load Balancing
Anything that doesn't need an answer in seconds belongs on a batch API: OpenAI and Anthropic both offer 50% discounts for asynchronous jobs completed within 24 hours (usually much faster — median under an hour off-peak). Ideal agent workloads: nightly data enrichment, bulk document summarization, evaluation runs, embedding backfills. Batch traffic also doesn't count against your interactive RPM/TPM limits, which effectively doubles your capacity for free.
Multi-provider load balancing spreads sustained load across vendors — route by task type (cheap model for routing/extraction, frontier model for reasoning), then across providers within a class. Gateways like LiteLLM, OpenRouter, or a homegrown router give you a single choke point for the token buckets, budget accounting, and failover in one place. Keep prompts provider-portable and validate outputs identically regardless of upstream vendor; our multi-provider routing writeup covers the tradeoffs.
Protecting Your Own APIs From Your Agents
The overlooked half of agent rate limiting: your agents are clients of your infrastructure too. An agent with a search_orders tool can hammer your production database with the enthusiasm of a load test. Defenses:
- Tool-level rate limits. Each tool declares its own budget (e.g.,
search_orders: 10 calls/task, 60/minute globally). Enforce in the tool executor, not in the prompt — models don't reliably obey "please don't call this too often." - Separate service credentials for agents. Agents authenticate to internal APIs with their own identity so you can throttle, audit, and revoke them independently of human traffic.
- Read replicas and result caps. Point read-heavy tools at replicas; cap result sets (LIMIT 50) so one tool call can't return a 2M-row table into your context window.
- Backpressure as tool output. When a tool is throttled, return a structured "rate limited, retry after 30s" message to the model — well-prompted agents will reschedule or proceed with other work.
This mirrors the guidance in OWASP's LLM Top 10 on Unbounded Consumption: unmetered tool access is both a cost bug and a denial-of-service vector.
Monitoring and Alerting
Instrument the gateway, not the agents. The metrics that matter:
| Metric | Alert Threshold (starting point) | Why |
|---|---|---|
| 429 rate per provider | >1% of requests over 5 min | Your limiter is mistuned or tier too low |
| 529/503 rate per provider | >2% over 5 min | Provider incident — check failover |
| Queue wait time (p95) | >5s interactive | Users are feeling the throttle |
| Spend per hour | >1.5x trailing 7-day average | Runaway task or abuse |
| Cache hit rate (prompt cache) | <40% for multi-turn agents | Prompt structure broke caching |
| Cost per completed task (p95) | 2x your unit-economics target | Model regression or loop bug |
| Fallback provider share | >10% over 15 min | Primary degraded; quality may drift |
Tag every request with task ID, user ID, feature, and model so you can answer "who spent the money" in one query. Teams that can't segment spend by feature within 30 seconds always overspend — visibility is the control.
Related Reads
Key Takeaways
- Centralize rate limiting per provider key using a token bucket (~80% of RPM/TPM tier) + concurrency semaphore (start at 5-10 concurrent LLM calls) + priority queue to prevent 429 cascades from agent fan-out (20-30 LLM calls per user task).
- Enforce per-task token ($0.50-$5) and dollar caps ($10-$50) with incremental cost tracking on every API response, plus an org-level kill switch (2-3x expected daily spend) to halt non-critical traffic in under a minute.
- Cut input costs 40-90% by structuring prompts with static content first (system message, tools, few-shot examples) to leverage provider-side prompt caching (10-50% of normal input token cost), and cache deterministic responses (15-30% hit rate) and embeddings (content-hash keyed) client-side.
- Offload non-interactive workloads to batch APIs (50% discount, no RPM/TPM impact) and use multi-provider load balancing (LiteLLM/OpenRouter) to route by task type and fail over during provider incidents (529/503 signals).
- Protect your own APIs from agent tool calls by enforcing tool-level rate limits (e.g., 10 calls/task, 60/minute globally), using separate service credentials, capping result sets (LIMIT 50), and returning structured backpressure messages to reschedule agent work.
- Monitor gateway metrics (429/529 rates, queue wait time, spend per hour, cache hit rate) with alerts at 1-2% thresholds, and tag every request by task/user/feature to segment spend and debug runaway costs in under 30 seconds.
Frequently Asked Questions
What concurrency limit should I start with for agent LLM calls?
Start with a semaphore of 5-10 concurrent requests per provider key and raise it while watching your 429 rate and TPM utilization. Most mid-tier accounts saturate TPM well before concurrency; frontier-model streaming calls holding connections open for 30-60s are the exception.
How is rate limiting different for agents vs chatbots?
Volume and unpredictability. A chatbot's load is proportional to user messages; an agent's load is user tasks × steps per task, and steps vary 10x between easy and hard tasks. Agents therefore need per-task budget caps and loop guards in addition to classic request-rate controls.
Does prompt caching really cut costs 90%?
On cached input tokens, yes — Anthropic bills cache reads at 10% of the base input rate. Whole-bill savings depend on your input/output mix: multi-turn agents with big system prompts and long histories typically see 40-70% total input-cost reduction. Output tokens are never discounted, so verbose agents benefit less.
Should I build my own gateway or use LiteLLM/OpenRouter?
Use an existing gateway until you have a reason not to. LiteLLM (self-hosted) or OpenRouter (hosted) give you unified APIs, key management, budgets, and failover out of the box. Build custom only when you need bespoke priority queuing, compliance isolation, or sub-10ms routing overhead.
How do I stop one user from consuming my entire provider quota?
Per-user daily dollar caps enforced at the gateway plus a fair-share scheduler: weighted round-robin across users in the priority queue so no single user's task fan-out monopolizes concurrency slots. Soft-block with a clear message at 100% of cap rather than silently degrading everyone else.


Comments
Sign in to join the conversation
No comments yet. Be the first to share your thoughts!