Skip to main content

The Token-Per-Minute Ceiling You Never Load-Tested

· 10 min read
Tian Pan
Software Engineer

The demo worked. The beta worked. Then the launch drove ten times the traffic into a token-per-minute quota you never load-tested against, and every user past the ceiling got a 429 at the exact moment you had the most eyes on the product.

This is the failure mode nobody rehearses. Teams load-test their own servers obsessively — replicas, connection pools, database indexes — and then route every request through a provider quota that lives in someone else's account, at a ceiling they've never actually touched. The rate limit isn't an error to catch in a try block. It's a hard product constraint, and if you haven't planned around it, the launch is the first time you'll find out where it sits.

The uncomfortable part is that the ceiling is invisible until you hit it. Your dashboards show latency and error rate, both healthy, because in dev and beta you never came close. The provider's limit is a cliff, not a slope: you're fine at 95% of your token-per-minute allowance and hard-failing at 101%. There's no gradual degradation warning you on the way up — just a wall you discover by walking into it, in front of your entire launch audience.

Why This Isn't Scaling Stateless Web Servers

Every instinct you built scaling web infrastructure is wrong here, and the wrongness is subtle enough to bite you.

When a stateless service gets hot, you add replicas. Capacity is something you own and can provision in minutes — spin up more containers, widen the autoscaling group, done. The constraint is your compute budget, and you control the dial.

With a hosted model, the constraint lives in someone else's account. Your token-per-minute (TPM) and requests-per-minute (RPM) limits are set by your provider tier, and no amount of scaling your fleet moves them. You can run a thousand application replicas behind a load balancer and every one of them draws from the same shared quota. Adding capacity on your side just means more clients racing to hit the same ceiling faster. The bottleneck moved outside your blast radius, and most of your scaling playbook doesn't reach it.

The limits themselves are also more textured than "requests per second." Providers meter on several axes at once — RPM, TPM, sometimes requests-per-day and tokens-per-day — and you hit whichever comes first. Anthropic splits the token dimension further, into input tokens per minute and output tokens per minute as separate buckets, so a workload heavy on long prompts can exhaust the input ceiling while the output ceiling sits idle. Your effective capacity isn't one number; it's the minimum across several, and the one that bites depends on the shape of your traffic, not just its volume.

And the tiers gate on spend, not on need. On OpenAI, higher tiers unlock as your cumulative platform spend crosses thresholds; Anthropic uses a similar spend-based ladder where the top tiers require thousands of dollars of history. A brand-new project on a low tier can be TPM-limited at a level that a launch spike blows through in seconds — and you can't buy your way up instantly, because the tier reflects history you don't have yet.

What You Actually Have to Forecast

"How many users" is the wrong unit. Provider limits are denominated in tokens per minute, so your forecast has to be too, and getting there means estimating a few things most teams skip.

Tokens per request, at the tail — not the average. A capacity plan built on the average request is a plan that fails on the interesting requests. The user pasting a 40-page contract into your summarizer consumes twenty times the tokens of the median query, and launch traffic surfaces exactly these power users first. Forecast the p95 and p99 token cost per request, because those are the requests sitting closest to the ceiling. Both input and output count against your quota, so a feature that produces long generations burns budget on the way out as well as the way in.

Peak concurrent requests, not daily volume. A rate limit is a per-minute bucket. "One million requests a day" tells you almost nothing; the same daily total can arrive as a flat trickle or as a 60-second thundering wall when your launch email goes out. What matters is how many requests land inside the same rolling minute, because that minute is what the provider meters.

The burst shape. A launch spike and steady-state traffic are different animals, and they fail differently. Steady state is a soak problem — can you sustain this for hours without a slow leak. A launch is a spike problem — a near-vertical ramp as a campaign, a press hit, or a viral post dumps traffic in seconds, then a long reconnect storm as retries pile on top of first-time requests. If you only ever tested a gentle ramp, you tested the wrong curve. The spike is where the reconnect storm doubles your effective load right when you have the least headroom.

Multiply it out: peak concurrent requests × p99 tokens per request, measured against your tier's per-minute ceiling. If that product exceeds the limit, you have a decision to make before launch, not a 429 to catch during it.

The Levers That Buy You Headroom

Once you know the ceiling is too low, there are four moves, and the most important one has a lead time measured in weeks.

Request the quota increase early. Tier upgrades that gate on spend aren't instant, and manual increase requests go through a queue with a human on the other end. If your capacity math says you need a higher limit, file the request weeks before launch — not the night before, when the approval won't land in time. Treat provider quota like any other long-lead-time dependency: order it ahead. This is the lever people discover they needed at 11 PM on launch eve, which is precisely when it's too late to pull.

Keep a fallback model tier for overflow. When you're rate-limited on the premium model, routing to a cheaper or smaller model beats failing outright — and the fallback often draws from a separate quota pool, so it's genuine additional headroom, not the same bucket by another name. A shorter, cheaper answer is a better user experience than a spinner that times out. Build the fallback ladder before you need it: primary model, then a secondary tier, then a degraded variant with trimmed context. The user gets an answer; you get to stay up.

Queue and degrade instead of hard-failing. A 429 handed straight to the user is the worst outcome. With admission control and a queue, an over-the-ceiling request waits a beat instead of dying — the queue absorbs the spike and drains it against your quota at a sustainable rate. When the queue itself fills, degrade deliberately: reject fast with a clear message, enqueue a shorter-context variant, or drop to the fallback pipeline. Backpressure turns a budget-melting incident into a slower-but-alive experience. The goal is that the ceiling produces slowness, never a wall.

Budget prompt length to stretch the same quota. Because the limit is denominated in tokens, every token you don't send is capacity you get back. Trimming bloated system prompts, capping retrieved context, and setting max_tokens to the output you actually expect all stretch the same ceiling further. Prompt caching helps too, where a provider discounts repeated prefix tokens. This is the one lever that costs you nothing and helps immediately — you're not buying more room, you're using less of it per request.

One caveat that quietly wrecks capacity plans: retries. Naive retry-on-429 amplifies a spike into a self-inflicted denial of service, because every throttled client fires again into an already-saturated bucket. Use exponential backoff with jitter, respect the Retry-After header the provider sends on the 429, and never retry non-retryable errors — a 400 retried is just quota set on fire. Your retry policy is part of your capacity plan, not a detail below it.

Load-Test the Ceiling Before Your Users Do

None of the forecasting matters if you never exercise the limit. The point of a load test here isn't to prove your servers are fast — it's to walk your traffic straight into the provider ceiling in a controlled setting so you learn where the cliff is on your terms.

Build a realistic prompt corpus. Fifty to a hundred prompts drawn from your actual production distribution — short queries, long-context requests, multi-turn conversations, the pathological edge cases — and randomize the selection during the test. A load test that fires the same short prompt ten thousand times tells you nothing about the TPM ceiling, because token cost is what the ceiling meters and a uniform prompt hides the variance that matters.

Test the spike shape, not just a gentle ramp. Ramp gradually first to find the inflection point where latency and error rate start to bend — that's your real ceiling, usually below the number in the docs. Then run an actual spike test: jump to launch-level concurrency in seconds and watch what breaks, because that near-vertical curve is what a launch delivers. Add a soak test at sustained load to catch the slow degradations a short burst hides.

Measure the metrics that reveal saturation, which are not the ones from classic web load testing. Time-to-first-token shows when the model starts responding under pressure. Tokens per second measures the real throughput you're getting. And p95/p99 latency shows exactly when your slowest users start to suffer — averages will lie to you here, because LLM response times vary enough that the mean stays comfortable while the tail is already on fire.

One honest warning: this test costs real money, because you're paying for every token you fire. A load test that pushes ten thousand long-context requests can run into real dollars, and that cost is the point — it's the price of knowing your ceiling before your users find it for you. Budget for it, run it against a realistic tier, and treat the invoice as cheap insurance against a melted launch.

The Ceiling Is a Design Input, Not an Exception

The mental shift is small and it changes everything: stop treating the rate limit as an error to catch and start treating it as a fixed dimension of your product, like latency or cost. It has a number. That number is knowable before launch. And every architectural decision — which model, how long the prompt, whether to queue, when to degrade — is really a decision about how you spend a per-minute budget you don't fully control.

Teams that ship through launches without melting have all done the same unglamorous work: they forecast tokens per minute at the tail, they requested the quota bump weeks ahead, they built the fallback ladder before they needed it, and they load-tested the spike until they'd seen the cliff with their own eyes. The launch was boring because the hard part happened in the weeks before it. Do that work, and the 429 becomes a line in a runbook instead of the story of your launch day.

References:Let's stay in touch and Follow me for more thoughts and updates