429 Too Many Requests
Exceeding the allowed request rate triggers the 429 Too Many Requests status code, also known as "rate limiting".
Usage
The 429 Too Many Requests status code indicates the number of HTTP requests has exceeded the allowed threshold. This happens, for example, when the server wants to limit the number of API calls in an hour.
The specification does not define how the server counts HTTP requests or identifies users. Rate limiting is done on a per-resource basis, or per-user basis, across the entire server, or across several servers. User identification is accomplished using credentials or alternatively, by using Cookies.
The server optionally includes a Retry-After HTTP header to inform the client when requests are accepted again.
Note
Rate limiting caps the total number of requests in a time window (hard cutoff) while throttling slows down request processing by queuing or delaying responses. The wait duration depends on the Retry-After header. Without Retry-After, common windows range from 60 seconds to 24 hours depending on the API. VPN users share IP addresses with many other users, so per-IP rate limits affect all VPN users on the same server.
SEO impact
Googlebot treats 429 as a server error
signal. When a site returns 429 responses,
Google temporarily reduces the crawl rate across
the entire site. Once normal responses resume,
the crawl rate gradually recovers. Unlike other
4xx codes, 429
responses affect crawl budget.
Persistent 429 responses on indexed URLs
lead to removal from search results. To slow
Googlebot down, 429 is the correct status
code. 401 and 403 do not reduce the
crawl rate. Bingbot also reduces its crawl rate
on 429 responses. Bing additionally supports
crawl-delay in robots.txt as an alternative
to status-code-based throttling.
Example
The client requests a resource and the server responds with 429 Too Many Requests.
Request
GET /current-news HTTP/1.1
Host: www.example.re
Response
HTTP/1.1 429 Too Many Requests
Retry-After: 1800
Content-Type: text/html
Content-Length: 173
<html>
<head>
<title>Request Limit Exceeded</title>
</head>
<body>
<p>The request limit has been reached.
Try again in 30 minutes.</p>
</body>
</html>
How to fix
Check the Retry-After header in the response. The value specifies either a number of seconds or an HTTP date indicating when the server accepts requests again. Pause all requests until the indicated time.
Implement exponential backoff with jitter between retry attempts. Double the wait time after each failure (1s, 2s, 4s, 8s) and add a random offset to prevent multiple clients from retrying at the same instant and creating a new traffic spike.
Monitor rate-limit headers before hitting the
ceiling. Many APIs include X-RateLimit-Limit,
X-RateLimit-Remaining, and X-RateLimit-Reset
headers. Track the remaining count and slow down
requests proactively.
Queue outgoing requests on the client side. A request queue with a controlled dispatch rate prevents bursts from exceeding the limit. Batch multiple operations into a single API call when the endpoint supports bulk operations.
Cache responses for data not expected to change between requests. Redundant identical calls are the most common source of unnecessary rate-limit consumption.
On the server side in nginx, the limit_req_zone
and limit_req directives control per-IP or
per-endpoint rate limits. Set limit_req_status 429;
so rate-limited requests return the correct status
code instead of the default 503. Use burst
and
nodelay parameters to allow short traffic spikes
without immediately rejecting clients.
For AWS API Gateway, configure throttle settings at the stage or method level. Increase the rate and burst capacity to match expected traffic patterns when the default thresholds are too restrictive.
Code references
.NET
HttpStatusCode.TooManyRequests
Rust
http::StatusCode::TOO_MANY_REQUESTS
Rails
:too_many_requests
Go
http.StatusTooManyRequests
Symfony
Response::HTTP_TOO_MANY_REQUESTS
Python3.5+
http.HTTPStatus.TOO_MANY_REQUESTS
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_TOO_MANY_REQUESTS
Angular
@angular/common/http/HttpStatusCode.TooManyRequests
See also
- RFC 6585: Additional HTTP Status Codes
- Google: HTTP status codes and network errors
- 420
- Retry-After
- HTTP status codes