← Back to Blog
December 5, 202411 min read

Distributed Rate Limiting with Redis: Scaling API Protection

RedisRate LimitingAPIScalability

Rate limiting prevents abuse, but in a distributed system, you need shared state. Redis provides the perfect solution for distributed rate limiting across multiple server instances.

Sliding Window Algorithm

The sliding window algorithm provides smooth rate limiting. Use Redis sorted sets to track request timestamps, removing old entries and checking if the current window exceeds the limit.

// Redis sliding window implementation
const key = `rate_limit:${userId}`;
const now = Date.now();
const windowMs = 60000; // 1 minute
const maxRequests = 100;

// Remove old entries
await redis.zremrangebyscore(key, 0, now - windowMs);

// Count current requests
const count = await redis.zcard(key);

if (count >= maxRequests) {
  return { allowed: false };
}

// Add current request
await redis.zadd(key, now, `${now}-${Math.random()}`);
await redis.expire(key, Math.ceil(windowMs / 1000));

return { allowed: true };

Token Bucket Pattern

The token bucket allows bursts while maintaining average rate. Tokens are added at a steady rate, and requests consume tokens. This is more flexible than fixed windows.

Implementation Considerations

Use Redis Lua scripts for atomic operations. This ensures rate limiting logic executes atomically, preventing race conditions. Cache rate limit results briefly to reduce Redis load. Always expose rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) so API clients can implement back-off strategies without guessing.

Key Takeaways

  • Use Redis for distributed rate limiting — in-process counters do not work across multiple Node.js instances or serverless functions.
  • The sliding window algorithm is smoother than fixed windows and prevents burst traffic at window boundaries.
  • Token bucket allows natural burst handling for legitimate users with spiky usage patterns while still protecting your infrastructure.
  • Apply rate limiting at the middleware layer before any business logic runs to minimise unnecessary computation.
  • Different endpoints deserve different limits — authentication routes warrant much stricter limits (5–10 per minute) than read-heavy data endpoints (100–500 per minute).

Ready to Ship Your SaaS?

Stop writing the same boilerplate code. Browse our production-ready SaaS templates — each includes authentication, Stripe billing, database setup, and deployment configs so you can launch in days instead of months.

Check out our straightforward pricing, see how we compare to ShipFast and MakerKit, or read the documentation to understand exactly what you get. Questions? Learn about our team and mission, or catch up on our engineering blog.