The next scaling concern is hot-key distribution. A global limit stored under one Redis key can become a serialization point even when the cluster has plenty of total capacity. Per-tenant keys scale better, while truly global limits may require a hierarchical design.
Time handling is easy to underestimate in a distributed limiter. If application servers calculate refills using their own clocks, clock skew can produce inconsistent decisions. Keeping time calculation close to the authoritative Redis state makes the behavior easier to reason about.
Token bucket is a practical choice because it separates the sustained rate from the permitted burst size. Those two values should be configured independently; otherwise, increasing throughput may accidentally allow much larger traffic spikes than the downstream service can absorb.
Using a Lua script for refill, validation, and token consumption is the key step here. Without atomic execution, concurrent clients can read the same token count and both succeed, allowing the real request rate to exceed the configured limit.
haleo
A production rate limiter also needs an explicit failure policy. When Redis is slow or unavailable, should the service fail open, fail closed, or temporarily use a local fallback? The correct answer depends on whether availability, cost protection, or abuse prevention is the higher priority.