Transactions, Scripting, and PipelinesLesson 5.5
Rate limiting with Redis: sliding window and token bucket patterns
rate limiting use case, fixed window counter, sliding window log with Sorted Set, token bucket with INCR and TTL, MULTI/EXEC for atomicity, rate limit headers
Rate limiting in Redis
Redis is the standard backend for API rate limiters. Its atomic increment and TTL support make it ideal.
Fixed window (simplest)
async function isAllowed(userId, limit = 100) {
const key = `ratelimit:${userId}:${Math.floor(Date.now() / 60000)}`;
const count = await client.incr(key);
if (count === 1) await client.expire(key, 60); // first request sets TTL
return count <= limit;
}Flaw: a client can make 200 requests by hitting 100 at the end of one window and 100 at the start of the next.
Sliding window log with Sorted Set
async function isAllowedSliding(userId, limit = 100, windowMs = 60000) {
const now = Date.now();
const key = `ratelimit:sliding:${userId}`;
await client.zRemRangeByScore(key, 0, now - windowMs); // remove old
const count = await client.zCard(key);
if (count >= limit) return false;
await client.zAdd(key, { score: now, value: `${now}` });
await client.pExpire(key, windowMs);
return true;
}Each request timestamp is stored as a Sorted Set member. Old entries are pruned on each check. This gives accurate per-second precision. The tradeoff is O(N) memory per user per window.
