Without rate limiting, one buggy client or one attacker can exhaust your database, blow your cloud bill, or take the service down for everyone. Here are the algorithms and a practical implementation.
The Main Algorithms
- Fixed window: simple counter per time window. Cheap, but allows bursts at window edges.
- Sliding window: smooths out the edge-burst problem with a rolling count.
- Token bucket: refills tokens at a steady rate; allows controlled bursts. The most popular.
A Redis Sliding-Window Limit
async function allow(userId, limit = 100, windowSec = 60) {
const key = `rl:${userId}`;
const count = await redis.incr(key);
if (count === 1) await redis.expire(key, windowSec);
return count <= limit;
}Tell the Client
Return 429 Too Many Requests with Retry-After and X-RateLimit-Remaining headers so well-behaved clients can back off gracefully instead of hammering you.
Limit by the Right Key
Rate-limit by API key or user ID for authenticated routes, and by IP for public ones. Layer both for login endpoints to stop credential-stuffing.
