back to blog

Designing a Rate Limiting Library in Node.js

Node.jsRate LimitingInfrastructure

During peak trading hours, CoinSwitch's APIs were getting hammered — some users hitting endpoints 100x/second. We needed a rate limiter that could handle this without adding latency. Here's how I built one supporting two algorithms.

Two Algorithms, One Interface

The library exposes a single isAllowed(key, config) interface but supports both Fixed Window and Leaky Bucket under the hood. This lets teams choose the right algorithm per use case.

Fixed Window

  Window: 1 minute
  Limit:  100 requests

  Time ──────────────────────────────────────────▶
       │◄── Window 1 ──▶│◄── Window 2 ──▶│
       │                 │                 │
       │  ████████░░░░  │  ██░░░░░░░░░░  │
       │  72/100        │  15/100        │
       │                 │                 │
  ─────┴─────────────────┴─────────────────┴─────

  Pros: Simple, O(1) Redis operations
  Cons: Burst at window boundaries

Leaky Bucket

  Rate: 10 requests/second
  Bucket size: 50

         ┌─────────┐
  req ──▶│ ████    │  ← Bucket (50 capacity)
  req ──▶│ ██████  │
  req ──▶│ ████████│
         └────┬────┘
              │ drip (10/sec)
              ▼
         ┌─────────┐
         │ Process  │
         └─────────┘

  Pros: Smooth output rate, no bursts
  Cons: Slightly more complex state

Redis-Backed State

Both algorithms use Redis for state, so they work correctly across multiple Node.js processes. The fixed window uses a simple INCR + EXPIRE combo. The leaky bucket uses a sorted set with timestamps.

Results

10% increase in system stability during peak hours. Zero false positives on legitimate traffic. The library is now the standard rate limiter across all CoinSwitch Node.js services.