← Back to all snippets
JAVASCRIPT

Client-Side API Request Rate Limiting (Token Bucket)

Implement a client-side token bucket algorithm to rate limit your API calls, preventing your application from exceeding API usage limits and ensuring a consistent request flow for better user experience.

class RateLimiter {
  constructor(maxTokens, refillRatePerSecond) {
    this.maxTokens = maxTokens;
    this.tokens = maxTokens;
    this.refillRate = refillRatePerSecond / 1000; // tokens per ms
    this.lastRefillTime = Date.now();
  }

  _refillTokens() {
    const now = Date.now();
    const timeElapsed = now - this.lastRefillTime;
    this.tokens = Math.min(this.maxTokens, this.tokens + timeElapsed * this.refillRate);
    this.lastRefillTime = now;
  }

  async acquireToken() {
    return new Promise(resolve => {
      const check = () => {
        this._refillTokens();
        if (this.tokens >= 1) {
          this.tokens--;
          resolve(true);
        } else {
          const timeToWait = (1 - this.tokens) / this.refillRate;
          setTimeout(check, Math.max(0, timeToWait + 1)); // Add 1ms buffer
        }
      };
      check();
    });
  }

  async makeRequest(apiCallFunc, ...args) {
    await this.acquireToken();
    return apiCallFunc(...args);
  }
}

// Usage example:
// const apiLimiter = new RateLimiter(5, 1); // 5 tokens initially, 1 token per second
//
// const fetchData = async (id) => {
//   console.log(`Fetching data for ${id} at ${new Date().toLocaleTimeString()}`);
//   // Simulate an API call
//   return new Promise(resolve => setTimeout(() => resolve(`Data for ${id}`), 500));
// };
//
// for (let i = 0; i < 10; i++) {
//   apiLimiter.makeRequest(fetchData, i)
//     .then(result => console.log(result))
//     .catch(err => console.error(err));
// }
How it works: This JavaScript snippet provides a client-side rate limiting solution using the token bucket algorithm. The `RateLimiter` class allows you to define a maximum number of tokens and a refill rate. When an API request is made, it first attempts to acquire a token. If no tokens are available, the request is delayed until a token becomes available based on the refill rate. This prevents your application from making too many requests in a short period, helping to avoid hitting server-side API rate limits and ensuring stable communication.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs