codejump
MediumPythonJavaScriptTypeScript

System Design — Sliding Window Counter Rate Limiter

System DesignRate LimitingSliding Window

A fixed-window counter lets a client burst twice the limit around a window boundary; a sliding
window log is exact but stores every timestamp. The sliding window counter is the
production compromise: keep only two numbers (the previous and the current window's counts)
and weight the previous window by how much of it still overlaps the sliding window.

solve(args, ops) builds new SlidingWindowCounter(limit, windowSize) —
args = [limit, windowSize] — and replays ops:

  • allow(timestamp) — return true and count the request, or false and count nothing.

Time is split into fixed windows: window w = floor(timestamp / windowSize), and
elapsed = timestamp - w * windowSize. Timestamps never go backwards. The estimated load is

estimate = prev * (windowSize - elapsed) / windowSize + current

A request is allowed when estimate < limit (before counting it). Compare in integers —
prev * (windowSize - elapsed) + current * windowSize < limit * windowSize — to avoid
floating-point surprises. When the window changes, prev becomes the old current if the new
window directly follows it, or 0 if one or more whole windows were skipped; current restarts at 0.

Example (limit = 1, windowSize = 10)

allow(0) → true   allow(5) → false   allow(10) → false   allow(11) → true

Sample tests

Test #1Limit of 3 per 10 with a weighted previous window
Input: [[3,10],[["allow",1],["allow",2],["allow",3],["allow",4],["allow",12],["allow",13],["allow",25],["allow",60]]]
Output: [true,true,true,false,true,false,true,true]
Test #2The previous window fades out
Input: [[1,10],[["allow",0],["allow",5],["allow",10],["allow",11]]]
Output: [true,false,false,true]
Test #3Burst in a single window
Input: [[2,5],[["allow",100],["allow",100],["allow",100]]]
Output: [true,true,false]