error http
HTTP 429 Too Many Requests
Understanding HTTP 429 Too Many Requests - the user has sent too many requests in a given time period (rate limiting).
What It Means
HTTP 429 Too Many Requests indicates that the user has sent too many requests in a given amount of time (“rate limiting”). The response should include a Retry-After header indicating how long to wait before making a new request.
Common Causes
- Exceeding API rate limits (e.g., GitHub, Twitter, Stripe APIs)
- Too many login attempts (brute-force protection)
- Aggressive polling or scraping without respecting rate limits
- Missing rate limit handling in client code
- Multiple services or users sharing the same API key
- Bot traffic triggering DDoS protection
How to Fix
Client-side: Respect rate limits
async function fetchWithRateLimit(url, options = {}) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter ? parseInt(retryAfter) * 1000 : 60000;
console.log(`Rate limited. Retrying after ${waitTime}ms`);
await new Promise(resolve => setTimeout(resolve, waitTime));
return fetchWithRateLimit(url, options);
}
return response;
}
Exponential backoff
async function fetchWithBackoff(url, options = {}, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
const retryAfter = response.headers.get('Retry-After');
const delay = retryAfter
? parseInt(retryAfter) * 1000
: Math.min(1000 * Math.pow(2, attempt), 30000);
await new Promise(resolve => setTimeout(resolve, delay));
}
throw new Error('Max retries exceeded');
}
Server-side: Implement rate limiting (Express.js)
const rateLimit = require('express-rate-limit');
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per window
standardHeaders: true, // Return rate limit info in headers
legacyHeaders: false,
message: {
error: 'Too Many Requests',
message: 'You have exceeded the rate limit. Please try again later.'
}
});
app.use('/api/', apiLimiter);
Python requests with retry
import requests
import time
def fetch_with_retry(url, max_retries=5):
for attempt in range(max_retries):
response = requests.get(url)
if response.status_code != 429:
return response
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Waiting {retry_after}s...")
time.sleep(retry_after)
raise Exception("Max retries exceeded")
Nginx rate limiting
# Define rate limit zone
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_req_status 429;
}
}