Recommended Free Tools
A Redis sliding-window counter estimates requests in a rolling interval by combining the current fixed-window count with a fraction of the previous window’s count. It smooths the burst loophole at fixed-window boundaries while storing only two counters per identity in the tutorial implementation—not every request timestamp. The trade-off is that the result is an estimate, not an exact rolling count.
How the sliding-window counter works
Divide time into fixed windows of duration W. For a request arriving in the current window, let C be the current-window count, P the previous-window count, and r the fraction of the current window that has elapsed. Estimate the rolling-window total as:
As an Amazon Associate I earn from qualifying purchases.
estimated_count = C + P × (1 − r)
The previous window is weighted by the portion that still overlaps the rolling interval. At the start of a new window, nearly all of the preceding window overlaps; as time passes, its contribution falls. The current count is added at full weight.
Illustrative example
Suppose the limit is 100 requests per minute, the previous window recorded 80, and 15 seconds have elapsed in the current 60-second window. The previous-window weight is (60 − 15) ÷ 60 = 0.75, so its estimated contribution is 60. If the current count is 25, the estimate is 85. These values illustrate the calculation; they are not measured performance or accuracy results.
#1 Best Overall
A limiter can compare the estimate with its configured limit before admitting a request, then increment the current counter if allowed. Because the previous count is weighted rather than treated as wholly in or out, the approach avoids the sharp accounting reset of a fixed window. But it cannot know the exact timestamps of requests within either window, so the estimate can differ from a true rolling count.
Implementing the decision in Redis
Redis’s tutorial implementation stores the current and previous counts as two string keys. A Lua script reads those counts, calculates the weighted estimate, decides whether the request is permitted, and increments the current counter in one server-side operation. Keeping the read-decide-update sequence atomic prevents concurrent service instances from interleaving their decisions and updates. Redis’s broader guidance describes this shared-state pattern for quotas scoped to a user, IP address, API key, tenant, or model.
Rank #2
The tutorial expires the current-window key when it is first created. If using Redis Cluster, its example gives the two keys a common hash tag so they map to the same cluster slot, which is necessary for a script that operates on both keys. These are implementation details of that tutorial, not universal requirements for every rate limiter. See the Redis rate-limiting tutorial and Redis rate-limiter guidance.
Keep increment and expiry together
A simpler counter pattern can fail if INCR succeeds but the separate EXPIRE command does not: the counter may remain without an expiry. Redis documents using Lua to make increment-and-expire operations atomic. The same principle matters when a limiter has multiple dependent steps: decide and update shared state as one operation rather than relying on separate client round trips. See Redis INCR documentation.
Rank #3
Redis 8.8 and INCREX
Redis 8.8 documentation describes INCREX, a native operation combining counter increments, bounds, and expiration. It may simplify some counter-based limiter patterns. It should not be treated as a direct implementation of the weighted two-counter sliding-window algorithm unless its exact command semantics match the intended design and the deployment actually runs a compatible version. See Redis INCREX documentation.
Choose an algorithm by its boundary accuracy and burst policy
| Algorithm | Boundary behavior and accuracy | Storage pattern | Burst behavior and complexity |
|---|---|---|---|
| Fixed window | Counts within discrete windows; requests can cluster on opposite sides of a boundary. | One counter per active window in a basic implementation. | Simple, but can allow a boundary burst across adjacent windows. |
| Sliding-window log | Counts retained request timestamps for an exact rolling-window view in the Redis tutorial comparison. | Stores individual timestamps, commonly in a sorted set; storage grows with retained requests. | More precise, with more per-request storage and cleanup work. |
| Sliding-window counter | Uses a weighted previous-window count; smooths boundaries but estimates rather than exactly counting. | Two string counters per identity in the tutorial example. | Moderate implementation complexity; storage-efficient compared with retaining each timestamp. |
| Token bucket | Not primarily a window-boundary counter. | Tracks bucket state rather than every request timestamp. | Useful when policy should allow controlled bursts. |
| Leaky bucket | Not primarily a window-boundary counter. | Tracks the bucket or queue state. | Useful for strict no-burst behavior; distinguish policing, which rejects excess traffic, from shaping, which queues or delays it. |
Algorithm descriptions and qualitative comparisons follow Redis’s rate-limiting tutorial. The tutorial’s author, William Johnston, wrote, “There’s no single best algorithm,” in the March 20, 2026 tutorial. Its comparisons are qualitative, not benchmark results; no throughput, latency, memory, or accuracy measurements are established here.
Rank #4
Decide whether this trade-off fits your quota
- Choose a sliding-window counter when smoothing fixed-window edges and keeping per-identity state small matter more than an exact request-by-request rolling count.
- Choose a sliding-window log when exact rolling-window accounting is essential and retaining individual request timestamps is acceptable.
- Choose a token bucket when the policy intentionally permits a controlled burst, or a leaky bucket when excess bursts must be prevented or smoothed through shaping.
- Use a fixed window when simplicity is the priority and its boundary burst behavior is acceptable.
For any design, define the quota’s identity and scope explicitly, and ensure every service instance consults the same shared state. Then choose the burst policy and accounting accuracy the application actually needs; there is no universally best rate-limiting algorithm.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




