search
Tutorials

Fix: 429 Too Many Requests error

Quick fix for '429 Too Many Requests' error. Learn how to implement rate limiting and handle API rate limits effectively.

person By Gautam Sharma
calendar_today January 8, 2026
schedule 3 min read
Rate Limiting API HTTP Error Fix Performance

The ‘429 Too Many Requests’ error occurs when a client exceeds the rate limit set by a server or API provider, indicating too many requests in a given time period.


How the Error Happens

❌ Error Scenario:

// ❌ This causes rate limiting
async function makeManyRequests() {
  for (let i = 0; i < 1000; i++) {
    // ❌ No rate limiting - sends requests too quickly
    await fetch('/api/data'); // ❌ Will hit rate limit
  }
}

✅ Quick Fix - Implement Rate Limiting

Solution 1: Client-Side Request Throttling

// ✅ Throttle requests with delays
async function throttledRequest(url, delay = 100) {
  const response = await fetch(url);
  
  if (response.status === 429) {
    // ✅ Handle rate limit response
    const retryAfter = response.headers.get('Retry-After') || delay;
    await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
    return throttledRequest(url, delay); // ✅ Retry after delay
  }
  
  return response;
}

// ✅ Use with delay between requests
async function makeRequests() {
  const urls = ['/api/1', '/api/2', '/api/3'];
  
  for (const url of urls) {
    const response = await throttledRequest(url);
    console.log(await response.json());
    await new Promise(resolve => setTimeout(resolve, 100)); // ✅ 100ms delay
  }
}

Solution 2: Token Bucket Rate Limiting

// ✅ Token bucket implementation
class TokenBucket {
  constructor(capacity, refillRate) {
    this.capacity = capacity; // ✅ Max tokens
    this.tokens = capacity; // ✅ Current tokens
    this.refillRate = refillRate; // ✅ Tokens per second
    this.lastRefill = Date.now();
  }
  
  async consume(tokens = 1) {
    this.refill();
    
    if (this.tokens >= tokens) {
      this.tokens -= tokens;
      return true; // ✅ Request allowed
    }
    
    // ✅ Calculate wait time
    const waitTime = (tokens - this.tokens) / this.refillRate * 1000;
    await new Promise(resolve => setTimeout(resolve, waitTime));
    return this.consume(tokens);
  }
  
  refill() {
    const now = Date.now();
    const tokensToAdd = (now - this.lastRefill) / 1000 * this.refillRate;
    this.tokens = Math.min(this.capacity, this.tokens + tokensToAdd);
    this.lastRefill = now;
  }
}

// ✅ Usage
const bucket = new TokenBucket(10, 1); // ✅ 10 requests, 1 per second

async function makeLimitedRequest(url) {
  await bucket.consume(); // ✅ Consume a token
  return fetch(url);
}

Solution 3: Server-Side Rate Limiting

// ✅ Express.js rate limiting middleware
const rateLimit = require('express-rate-limit');

// ✅ Basic rate limiter
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // ✅ 15 minutes
  max: 100, // ✅ Limit each IP to 100 requests per windowMs
  message: 'Too many requests from this IP, please try again later.',
  standardHeaders: true, // ✅ Return rate limit info in headers
  legacyHeaders: false, // ✅ Disable X-RateLimit headers
});

app.use('/api/', limiter);

// ✅ Custom rate limiter for specific endpoints
const apiLimiter = rateLimit({
  windowMs: 60 * 1000, // ✅ 1 minute
  max: 10, // ✅ 10 requests per minute
  skipSuccessfulRequests: true // ✅ Only count failed requests
});

app.post('/api/login', apiLimiter, (req, res) => {
  // ✅ Login route with rate limiting
});

Solution 4: Retry with Exponential Backoff

// ✅ Retry with exponential backoff
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
  for (let i = 0; i <= maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        if (i === maxRetries) {
          throw new Error('Rate limit exceeded after retries');
        }
        
        // ✅ Calculate exponential backoff
        const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i) * 1000;
        await new Promise(resolve => setTimeout(resolve, retryAfter));
        continue;
      }
      
      return response;
    } catch (error) {
      if (i === maxRetries) throw error;
      // ✅ Retry on network errors too
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
    }
  }
}

// ✅ Usage
const response = await fetchWithRetry('/api/data');
Gautam Sharma

About Gautam Sharma

Full-stack developer and tech blogger sharing coding tutorials and best practices

Related Articles

Tutorials

Fix: API rate limit exceeded error

Quick fix for 'API rate limit exceeded' error. Learn how to handle API rate limits and implement proper request throttling.

January 8, 2026
Tutorials

Fix: CORS preflight response is invalid error

Quick fix for 'CORS preflight response is invalid' error. Learn how to properly configure CORS headers for preflight requests.

January 8, 2026
Tutorials

How to Fix: 403 Forbidden Error - Complete Tutorial

Complete guide to fix 403 Forbidden errors. Learn how to resolve permission issues with practical solutions, authorization management, and best practices for secure API communication.

January 8, 2026