429 Too Many Requests
The client sent too many requests in a given amount of time.1 The server can say when to try again in a Retry-After header. It is defined in RFC 6585, not in the core HTTP specification.
- Class 4xx client error
- Retry after a delay
- Header Retry-After
Open cURL Builder Build a verbose request that shows the response headers, Retry-After included.
Common causes
- A loop or a batch job calls the API faster than the plan allows.
- Retries without backoff turn one failure into a burst of requests.
- Many users share one IP address (an office network, CI runners), so a per-IP limit trips for all of them.
- Several workers share one API key, and with it one quota.
How to fix it
- Read
Retry-After: a number of seconds, or an HTTP date.2 Wait at least that long. - With no header, back off exponentially with jitter: 1 s, 2 s, 4 s, each plus a random offset, so clients don't retry in step.3
- Watch the remaining quota many APIs send (
X-RateLimit-Remainingon GitHub)4 and slow down before it reaches zero. - Cache responses and batch requests where the API allows it.
- On the server side, always send
Retry-After, so clients don't have to guess.
429 or 503?
429 is about you: this client went over its quota while others are served normally. 503 is about the server: it is overloaded or in maintenance for everyone.5 Both may carry Retry-After.
429 or 403?
Some APIs answer a rate limit with 403 (GitHub does for some limits, with a message saying so). If a 403 goes away on its own after a minute, it was a rate limit.
Example
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 30
{
"title": "Too Many Requests",
"status": 429,
"detail": "Limit of 100 requests per minute exceeded."
}Sources
- 1 RFC 6585, Additional HTTP Status Codes, section 4. rfc-editor.org ↩︎
- 2 RFC 9110, HTTP Semantics, section 10.2.3. rfc-editor.org ↩︎
- 3 AWS Architecture Blog, Exponential Backoff And Jitter. aws.amazon.com ↩︎
- 4 GitHub Docs, Rate limits for the REST API. docs.github.com ↩︎
- 5 RFC 9110, HTTP Semantics, section 15.6.4. rfc-editor.org ↩︎