Designing a Rate Limiting Library in Node.js
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.