Node.js › Caching with Redis

How would you implement a simple rate limiter using Redis's INCR command with expiration?

Intermediate

Answer

A fixed-window rate limiter increments a counter keyed by the client's identifier and current time window, setting an expiration on first creation of that key -- if the counter exceeds the allowed limit within the window before it expires, further requests are rejected; this leverages Redis's atomic INCR to safely handle concurrent requests from the same client without race conditions.
async function checkRateLimit(userId, limit = 100, windowSeconds = 60) {
  const key = `ratelimit:${userId}:${Math.floor(Date.now() / (windowSeconds * 1000))}`;
  const count = await client.incr(key);
  if (count === 1) await client.expire(key, windowSeconds);
  return count <= limit;
}
Real-world example A public API enforces a limit of 100 requests per minute per API key using this Redis-backed counter pattern, rejecting requests with a 429 status once a client exceeds the threshold within the current one-minute window, resetting automatically as each window's key expires.

Common follow-ups: What's the 'boundary burst' problem with fixed-window rate limiting, where a client could send double the limit across a window boundary?;How does a sliding-window-log approach using a Sorted Set address that boundary issue?