429
Too Many Requests
4xx Client Error

What Does HTTP 429 Too Many Requests Mean?

HTTP 429 indicates that the user has sent too many requests in a given amount of time ("rate limiting"). The server is protecting itself from being overwhelmed and is asking the client to slow down.

The response should include a Retry-After header indicating how many seconds the client should wait before making a new request. Many APIs also include custom headers showing rate limit details:

Rate limiting is not punishment — it is a necessary mechanism to ensure fair access for all API users and protect the server from abuse or accidental overload.

Common Causes

How to Handle 429 Errors

Exponential Backoff with Jitter (JavaScript)

async function fetchWithRetry(url, options = {}, maxRetries = 5) { for (let attempt = 0; attempt < maxRetries; attempt++) { const response = await fetch(url, options); if (response.status !== 429) return response; // Check Retry-After header first const retryAfter = response.headers.get('Retry-After'); let delay; if (retryAfter) { delay = parseInt(retryAfter, 10) * 1000; // seconds to ms } else { // Exponential backoff: 1s, 2s, 4s, 8s, 16s delay = Math.pow(2, attempt) * 1000; } // Add jitter (±20%) to prevent thundering herd delay += delay * (Math.random() * 0.4 - 0.2); console.log(`Rate limited. Retrying in ${Math.round(delay/1000)}s...`); await new Promise(r => setTimeout(r, delay)); } throw new Error('Max retries exceeded'); }

Python with requests

import time, random, requests 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 = response.headers.get('Retry-After') if retry_after: delay = int(retry_after) else: delay = (2 ** attempt) + random.uniform(0, 1) print(f"Rate limited. Waiting {delay:.1f}s before retry {attempt + 1}...") time.sleep(delay) raise Exception("Max retries exceeded")

Proactive Rate Limit Management

// Track your rate limit budget proactively class RateLimitedClient { constructor(requestsPerSecond) { this.interval = 1000 / requestsPerSecond; this.lastRequest = 0; } async request(url, options) { const now = Date.now(); const elapsed = now - this.lastRequest; if (elapsed < this.interval) { await new Promise(r => setTimeout(r, this.interval - elapsed)); } this.lastRequest = Date.now(); return fetch(url, options); } } // Use: max 10 requests/second const client = new RateLimitedClient(10); await client.request('https://api.example.com/data');

Implementing Rate Limiting (Server Side)

Nginx

# Rate limit: 10 requests/second per IP http { 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; # Include rate limit headers add_header X-RateLimit-Limit 10; proxy_pass http://backend; } } }

Express.js with express-rate-limit

const rateLimit = require('express-rate-limit'); const apiLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // 100 requests per window standardHeaders: true, // Return X-RateLimit-* headers legacyHeaders: false, handler: (req, res) => { res.status(429).json({ error: 'Too many requests', retry_after: Math.ceil(req.rateLimit.resetTime / 1000) }); } }); app.use('/api/', apiLimiter);

Frequently Asked Questions

What does HTTP 429 Too Many Requests mean?
It means you have exceeded the server's rate limit — you sent too many requests in too short a time. The server is asking you to slow down and try again later. Check the Retry-After header for how long to wait, and look for X-RateLimit-* headers to understand your limits.
How do I handle 429 errors in my code?
Use exponential backoff with jitter: wait 1s, then 2s, 4s, 8s between retries, adding random jitter to prevent all clients from retrying at the same time. Always respect the Retry-After header if present. Proactively throttle your requests to stay under the limit rather than hitting 429 and retrying.
How do I implement rate limiting on my API?
Use the token bucket or sliding window algorithm. Libraries like express-rate-limit (Node.js), django-ratelimit (Python), or Nginx's limit_req module handle this. Always return X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After headers so clients can self-throttle. Store rate limit state in Redis for multi-server deployments.

Related Status Codes

Related Tools