Rate limits and quotas
Two different limits, measured differently. A rate limit is about the next second; a quota is about the month. Both are visible before you hit them.
Last updated
The headers, on every response
These come back on successful responses too, not only on a 429. A client that only learns its limit by being refused cannot avoid being refused.
RateLimit: limit=30, remaining=27, reset=1
RateLimit-Policy: 30;w=1;burst=60;policy="token bucket"
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 27
X-RateLimit-Reset: 1On a 429 there is also Retry-After, in seconds. Honour it — it is the real number, and guessing is how a thundering herd gets built.
Per second
A token bucket, so a short burst above your steady rate is fine as long as the average holds. "30 requests a second, burst 60" means exactly that: you may spend 60 at once, and it refills at 30 a second.
| Plan | Steady | Burst |
|---|---|---|
| Free | 5 / second | 10 |
| Hobby | 10 / second | 20 |
| Starter | 30 / second | 60 |
| Pro | 100 / second | 200 |
Several buckets apply at once — your plan, the product, the individual key, the route — and all of them have to pass. Which one refused you is in details.policy on the 429.
Per month
Your plan includes a number of API requests per billing period. Reads served from your own cache do not count, which is most of the reason a sixty-second revalidate is worth more than an upgrade.
| Plan | Requests per month | Over the limit |
|---|---|---|
| Free | 10,000 | Refused with QUOTA_EXCEEDED |
| Hobby | 100,000 | Refused with QUOTA_EXCEEDED |
| Starter | 500,000 | Refused with QUOTA_EXCEEDED |
| Pro | 5,000,000 | Billed as overage rather than refused |
When the platform is at capacity
Above a concurrency ceiling an instance answers 503 SERVICE_UNAVAILABLE with a short Retry-After instead of queueing. That is deliberate. A refused request costs nothing and is survivable; a queued one is how an instance takes itself down, and everybody waiting behind it with it.
Treat a 503 as "try again in a moment", not as an outage. It means the platform chose to stay up.
Staying under
- Cache. A published post changes rarely and is read constantly.
- Ask for what you need:
?limit=100once beats twenty-five requests of four. - Use
includeand the relations already on a listing rather than a request per row. A listing returns its categories, tags and authors with it. - Read
RateLimit-Remainingand slow down before it reaches zero. - Back off exponentially with jitter when you are refused, and honour
Retry-Afterwhen it is present.