search
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.

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

The ‘API rate limit exceeded’ error occurs when your application exceeds the maximum number of requests allowed by an API provider within a specific time period.


How the Error Happens

❌ Error Scenario:

// ❌ This exceeds API rate limits
async function fetchUserData() {
  const userIds = [1, 2, 3, /* ... 1000 more */];
  
  // ❌ No rate limiting - hits API too quickly
  const promises = userIds.map(id => fetch(`/api/user/${id}`));
  return Promise.all(promises); // ❌ Will exceed rate limits
}

✅ Quick Fix - Handle API Rate Limits

Solution 1: Check Rate Limit Headers

// ✅ Monitor API rate limit headers
async function makeApiRequest(url) {
  const response = await fetch(url);
  
  // ✅ Check rate limit headers
  const remaining = response.headers.get('X-RateLimit-Remaining');
  const resetTime = response.headers.get('X-RateLimit-Reset');
  const limit = response.headers.get('X-RateLimit-Limit');
  
  if (response.status === 429 || parseInt(remaining) === 0) {
    // ✅ Rate limit exceeded
    const waitTime = (parseInt(resetTime) * 1000) - Date.now();
    await new Promise(resolve => setTimeout(resolve, waitTime + 1000));
    return makeApiRequest(url); // ✅ Retry after reset
  }
  
  return response;
}

Solution 2: Queue-Based Request Management

// ✅ Request queue with rate limiting
class ApiQueue {
  constructor(maxConcurrent = 5, interval = 1000) {
    this.maxConcurrent = maxConcurrent;
    this.interval = interval;
    this.queue = [];
    this.active = 0;
    this.running = false;
  }
  
  async add(requestFn) {
    return new Promise((resolve, reject) => {
      this.queue.push({ requestFn, resolve, reject });
      this.process();
    });
  }
  
  async process() {
    if (this.running || this.queue.length === 0 || this.active >= this.maxConcurrent) {
      return;
    }
    
    this.running = true;
    const { requestFn, resolve, reject } = this.queue.shift();
    this.active++;
    
    try {
      const result = await requestFn();
      resolve(result);
    } catch (error) {
      reject(error);
    } finally {
      this.active--;
      setTimeout(() => {
        this.running = false;
        this.process();
      }, this.interval);
    }
  }
}

// ✅ Usage
const apiQueue = new ApiQueue(10, 1000); // ✅ 10 requests per second

async function makeLimitedRequest(url) {
  return apiQueue.add(() => fetch(url));
}

Solution 3: API-Specific Rate Limiting

// ✅ GitHub API rate limiting example
class GitHubApi {
  constructor(token) {
    this.token = token;
    this.rateLimitReset = 0;
    this.remainingRequests = 5000; // ✅ GitHub's default
  }
  
  async request(endpoint) {
    // ✅ Wait if rate limit will be exceeded
    const now = Date.now();
    if (now < this.rateLimitReset && this.remainingRequests <= 1) {
      const waitTime = this.rateLimitReset - now + 1000;
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }
    
    const response = await fetch(`https://api.github.com${endpoint}`, {
      headers: {
        'Authorization': `token ${this.token}`,
        'User-Agent': 'MyApp/1.0'
      }
    });
    
    // ✅ Update rate limit info
    this.remainingRequests = parseInt(response.headers.get('X-RateLimit-Remaining')) || 0;
    this.rateLimitReset = parseInt(response.headers.get('X-RateLimit-Reset')) * 1000 || 0;
    
    if (response.status === 403 && response.headers.get('X-RateLimit-Remaining') === '0') {
      // ✅ Rate limit exceeded
      const resetTime = parseInt(response.headers.get('X-RateLimit-Reset')) * 1000;
      const waitTime = resetTime - Date.now() + 1000;
      await new Promise(resolve => setTimeout(resolve, waitTime));
      return this.request(endpoint); // ✅ Retry
    }
    
    return response;
  }
}

Solution 4: Bulk Operations and Caching

// ✅ Reduce API calls with bulk operations
class OptimizedApi {
  constructor() {
    this.cache = new Map();
    this.bulkRequests = new Map();
  }
  
  async getUserBulk(userIds) {
    // ✅ Group requests into bulk operations
    const uncachedIds = userIds.filter(id => !this.cache.has(id));
    
    if (uncachedIds.length > 0) {
      // ✅ Make single bulk request instead of multiple individual requests
      const response = await fetch('/api/users/bulk', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ids: uncachedIds })
      });
      
      const users = await response.json();
      users.forEach(user => {
        this.cache.set(user.id, user);
      });
    }
    
    return userIds.map(id => this.cache.get(id));
  }
  
  async getCached(key, fetchFn, ttl = 300000) { // ✅ 5 minutes default
    const cached = this.cache.get(key);
    if (cached && Date.now() - cached.timestamp < ttl) {
      return cached.data;
    }
    
    const data = await fetchFn();
    this.cache.set(key, { data, timestamp: Date.now() });
    return data;
  }
}

// ✅ Usage
const api = new OptimizedApi();
const users = await api.getUserBulk([1, 2, 3, 4, 5]); // ✅ Single request
Gautam Sharma

About Gautam Sharma

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

Related Articles

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.

January 8, 2026
Tutorials

Fix: Allowed memory size exhausted in WordPress error - Quick Solution

Quick fix for 'Allowed memory size exhausted' error in WordPress. Learn how to increase PHP memory limit and optimize WordPress performance.

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