How would you implement a distributed rate limiter across multiple instances of a microservice?
A rate limiter that only tracks state locally, such as a plain Semaphore or Guava's RateLimiter, only protects the single instance it's running in -- if you deploy ten pods of the same service, each one independently enforces the limit, so the effective total allowed traffic becomes N times the number of pods instead of N overall. To enforce a true global limit, you need shared state, typically kept in Redis using either a sliding-window or token-bucket algorithm. The check-increment-expire sequence needs to be atomic across concurrent requests hitting different pods, which is usually implemented as a single Redis Lua script executed with EVAL, called from Java through a client library such as Lettuce or Jedis. Rather than hand-rolling this, you can also lean on an existing framework, such as Resilience4j's RateLimiter backed by a Redis store, or the rate limiting built into Spring Cloud Gateway. Key design decisions include choosing between a fixed window, which is simple but can allow roughly double the intended burst right at window boundaries, a sliding window, which is more accurate but more expensive to compute, or a token bucket, which naturally smooths out bursts, as well as deciding whether the limit should apply per user, per IP address, or globally across the whole system.
Ready to master this question?
Generate a complete walkthrough — background, the full answer in plain language, a working code example explained line by line, a real-world scenario, common mistakes, and how this same question gets asked in different ways.
Sign in to generate a response