The five-hour and seven-day windows get all the attention. The per-minute ceilings — tokens per minute and requests per minute — are what actually trip during heavy moments. Here is what each measures, why a single big completion can saturate TPM, why a six-way sub-agent fan-out blows past RPM first, and what a token-aware router does that a round-robin one cannot.
TPM vs RPM — what each one really measures
Anthropic's per-account rate model has four windows. Two of them — the five-hour and seven-day rolling caps — measure aggregate usage over long time horizons. The other two operate at the minute level and are what we usually mean when we say "you got rate-limited":
- Tokens per minute (TPM) measures the byte throughput of conversations against your account. Both input tokens (system prompt, context, tool results, user prompts) and output tokens (model completions, tool calls) count. Streaming or batched, cached or fresh — all of it accumulates against the per-minute TPM budget.
- Requests per minute (RPM) measures the count of HTTP requests against
api.anthropic.comregardless of size. A request with two tokens of payload counts the same against RPM as a request with eighty thousand.
The two are enforced concurrently. Tripping either returns 429, and the response carries X-RateLimit-Remaining-Tokens, X-RateLimit-Remaining-Requests, X-RateLimit-Reset-Tokens, and X-RateLimit-Reset-Requests headers — one pair per dimension. The pair that hit zero is the one that produced the 429.
A tight TPM cap with a generous RPM cap fails in a specific way: a single large completion can saturate the entire minute's budget. The inverse — tight RPM with generous TPM — fails differently: parallel fan-out trips the count ceiling instantly even with light per-request payloads. Both shapes exist in the wild because different Anthropic plan tiers reshuffle the relative tightness of the two dimensions.
The way out is to read both pairs of remaining-counters on every response and route the next request to the account with room on whichever dimension is about to bind — which is what the budget-aware router in Power Claude does. It is a free install with no credit card if you want to watch it pick the right account while you read the rest of this.
Why a single big completion eats your TPM budget
Streaming completions are not free during their stream. The TPM accountant clocks tokens as they leave the wire. A 4K-token streaming response, while it streams, holds throughput at a meaningful fraction of the per-minute cap. The agent that requested the completion is committed to that throughput for the duration of the stream — sometimes thirty seconds, sometimes a minute or more.
A representative single-turn cost on a Pro account, with a 50K-token static context and a 4K output:
Input: 50,000 tokens (cached + dynamic)
Output: 4,000 tokens (streamed)
Total: 54,000 tokens against the per-minute TPM window
If the per-minute TPM budget is 80K (a representative subscription-tier number — check Anthropic's current docs for actuals), this single turn consumed two-thirds of the minute's headroom. The next concurrent request — even a tiny one — competes against the remaining 26K of TPM. A second 50K-input turn cannot land until the first one has rolled out of the minute window.
The pattern that catches developers is sequential heavy completions. Each completion individually fits inside the TPM cap. Run them back to back inside the same minute and they stack:
| Turn | Tokens | Cumulative TPM in window |
|---|---|---|
| Turn 1 (large completion) | 54,000 | 54,000 |
| Turn 2 (large completion, starts 20s later) | 54,000 | 108,000 |
| Turn 3 (large completion, starts 35s later) | 54,000 | 162,000 |
The fan-out problem — RPM is the silent killer
A six-way sub-agent fan-out does something different. The token volume per agent is moderate. The request count is the problem.
Parent dispatches 6 Task agents concurrently
↓
6 simultaneous POST /v1/messages requests against one account
↓
Each agent runs ~8 turns over 60s
↓
Each turn is at least 1 request (the completion)
↓
6 agents × 8 turns × 1 minute = 48 requests in the worst-case minute
If the per-minute RPM cap on the active account is 50 (a representative subscription tier number — verify against current Anthropic docs), the fan-out is one request away from tripping RPM. Add a single tool call to any agent's turn — which is a separate request from the completion — and the cap blows.
The order of operations matters. RPM trips on request initiation, before any tokens have flowed. TPM trips on token throughput, during the streaming. A heavy fan-out can produce a 429 on the seventh concurrent agent's POST before any of the agents have generated a single output token. The TPM cap is irrelevant in that moment — the requests never got far enough to consume throughput.
The diagnostic question when 429ing under fan-out is "which header zeroed out?" If X-RateLimit-Remaining-Requests is at zero with token budget remaining, RPM tripped. If X-RateLimit-Remaining-Tokens is at zero with request budget remaining, TPM tripped. The fix is different for each.
Per-account vs pooled accounting
Both TPM and RPM are per-account. Pooling N accounts gives you N parallel per-minute budgets — but only if traffic distributes evenly across the pool.
The naive distribution failure: round-robin routing sends agent one to account A, agent two to account B, agent three to account C, agent four to account A again. If account A's per-minute budget has not refilled yet from agent one, account A returns 429 on agent four's first request. The pool has six accounts available, but three of them have been routed-around because the round-robin position pointed at exhausted accounts.
The working distribution: per-request budget-aware routing. Before each new request, the router checks the most recent X-RateLimit-Remaining-* headers per account and routes to whichever account has the most projected remaining budget given the estimated size of this turn. Two implementation notes:
- Per-conversation stickiness. A sub-agent's turns should land on the same account across its lifetime. Otherwise the prompt cache evaporates — each new account is a fresh cache, and the cached system prompt has to be re-loaded at full token cost. The router picks an account when the sub-agent starts and stays there unless the account caps mid-flight.
- Cap-aware fallback. When the sticky account does cap, the fallback is another budget-aware pick, not the next account in order.
The result is that six concurrent sub-agents naturally distribute across six accounts (or six-of-N if the pool is larger), each with full per-minute headroom. No account is asked to serve more than one sub-agent's traffic. RPM cannot trip because no individual account sees the fan-out density.
Practical signals: how to know which one tripped
Anthropic returns useful headers on every response, success or 429. The relevant ones:
| Header | What it tells you |
|---|---|
X-RateLimit-Limit-Requests | RPM ceiling for this account |
X-RateLimit-Limit-Tokens | TPM ceiling for this account |
X-RateLimit-Remaining-Requests | RPM budget remaining in current minute |
X-RateLimit-Remaining-Tokens | TPM budget remaining in current minute |
X-RateLimit-Reset-Requests | When the RPM budget refills |
X-RateLimit-Reset-Tokens | When the TPM budget refills |
Retry-After | Seconds to wait before retrying (largest reset time) |
The raw transcript is the canonical record. Once a 429 has landed, parsing the transcript's last response headers is how you forensically determine which limit produced it. Productized tooling does this automatically. The grep-and-jq workflow does it for developers who want to inspect manually.
The architectural fix: token-aware routing
A working rotator does not pick the next account by position. It picks the next account by projected remaining budget, given the estimated cost of the request it is about to dispatch.
The decision logic, condensed:
def pick_account(accounts, request_size):
candidates = []
for account in accounts:
# Persist most recent rate-limit headers per account
tpm_remaining = account.headers['X-RateLimit-Remaining-Tokens']
rpm_remaining = account.headers['X-RateLimit-Remaining-Requests']
# Would this request fit?
if tpm_remaining > request_size and rpm_remaining > 1:
candidates.append((account, tpm_remaining, rpm_remaining))
# Pick the candidate with the most TPM headroom
return max(candidates, key=lambda x: x[1])
This is a sketch, not a full implementation. The real version handles:
- Estimated cost of the request (we do not know exact output size, but input size is known and output size has a typical range)
- Sticky session routing across multi-turn sub-agents
- Fallback when no account fits the request (queue, route to least-bad option, return 429 upstream)
- Reset-time arithmetic so we know when budgets will refill
The point is that the router has more state than a round-robin counter. The state — per-account, header-derived, per-request — is what turns a pool of N accounts into N× capacity instead of N× ping-pong. You can watch this land on six fresh accounts on your own machine before deciding anything: Install Power Claude Free ships the budget-aware router in a free download with a 7-day trial — no credit card.
Frequently asked questions
If I cache my system prompt, does prompt-cache traffic count against TPM?
Yes, under current Anthropic pricing. Cached reads cost less per token for billing purposes but count at full volume for TPM accounting. A 30K cached system prompt loaded on every turn draws 30K tokens per turn against the per-minute throttle. Caching reduces the bill, not the throttle pressure.
Does Claude Code's `/fast` mode raise my TPM, my RPM, or neither?
Neither. /fast changes how Anthropic prioritizes your request inside their serving queue. It does not change the per-account rate-limit ceilings. A /fast session still has the same TPM and RPM as a normal session on the same account.
Why does my account sometimes 429 on TPM with plenty of RPM headroom?
Large completions. A single 4K-token streaming response, with its 50K-token input context, consumes most of a typical per-minute TPM budget. Two of them within the same minute can saturate TPM regardless of how few requests you have made. The RPM headroom is irrelevant once TPM is at zero.
Can a proxy peek at the `X-RateLimit-*` headers and use them to route?
Yes. The headers are returned on every response. A proxy that terminates the upstream connection sees them. Persisting them per account and routing the next request by remaining budget is what distinguishes a working pool from a round-robin one. The headers are documented in Anthropic's API reference.
Do streaming completions count their tokens at completion or as they stream?
They count as they stream. The TPM accountant sees tokens as they cross the wire. A 30-second streaming completion holds your TPM throughput at the completion's rate for those thirty seconds. Concurrent requests in that window are competing against the remaining TPM budget in real time, not against the full per-minute cap that will exist once the stream finishes.
Closing
TPM and RPM are the per-minute ceilings that produce most of Claude Code's mysterious mid-session 429s. They are not the limits the docs spend the most time on, but they are usually the ones that trip first. The budget-aware router we ship reads the rate-limit headers on every response and routes the next request to whichever pooled account has the most headroom — the difference between a fan-out that works and one that 429s on the seventh agent.
To see what that saturation costs you in wall-clock time, drag the concurrency slider on the home page: it races a single account against a 5-account Balanced pool as you raise the number of concurrent sessions, and the gap it shows is exactly the mechanism described above made visible.
If you want to run the budget-aware router against a real fan-out of your own, the 14-day Premium Trial is $0 today and you can cancel anytime before day 15 — it adds Balanced Mode, the watchdog, and usage analytics on top of header-driven routing. Not ready to add a card? start the 7-day free trial instead — full Pro access, no credit card.