Course contentsShow
← Node.js
Lesson 676 of 1,9807. Web Framework Architecture and MiddlewareFree lesson

Rate Limiting with Redis

Distribute throttling state across multiple server instances using a centralized cache.

Rate Limiting with Redis

In this lesson, you will learn how to maintain a consistent rate-limiting policy across multiple server instances by offloading your throttling state to a centralized Redis cache.

The Problem with Local State

When you run a Node.js application in a cluster (as we discussed in our "Clustering Multiple Workers" module), you likely use an in-memory object to keep track of request counts per IP address. This works fine for a single process, but it fails in a distributed environment. If an incoming request hits Worker A, it has no idea how many requests that same user sent to Worker B. Consequently, a user could bypass your limits simply by hitting different instances of your server.

Centralizing the Throttle

To fix this, we move the "count" and the "expiration timer" out of the local memory and into Redis. Because Redis acts as a shared, high-speed data store, every server instance connects to the same source of truth.

When a request arrives, the middleware performs an atomic "increment and expire" operation in Redis. Here is the logic:

// Simplified middleware flow
async function rateLimit(req, res, next) {
  const userKey = `rate_limit:${req.ip}`;
  
  // Increment the request count in Redis
  const count = await redis.incr(userKey);
  
  // Set expiration if it's the first request
  if (count === 1) {
    await redis.expire(userKey, 60); // 1 minute window
  }

  if (count > 100) {
    return res.status(429).send("Too Many Requests");
  }
  
  next();
}

Why this scales

By using Redis, your rate-limiting state is decoupled from your application logic. Even if you spin up ten new server instances to handle a spike in traffic, they all verify the request count against the same centralized data. This ensures your API stays protected, regardless of how many workers are active or which server picks up the next request. This architecture keeps your "Request Sanitization" and "Feature Toggling" layers consistent across your entire infrastructure.

Key Takeaway: By offloading throttle counters to Redis, you ensure that rate limits are enforced globally across your entire server cluster rather than being siloed within individual worker instances.