~learn.
Code lab · World 01 · Data at Scale

Sliding window counter rate limiter.

Two counters per key and a weighted estimate fix the fixed window's boundary burst, in O(1) memory.

Medium~30 min2 example + 9 hidden tests+90 XPJump to the code ↓
Saving also stores the Python runtime (~13.5 MB, once for every lab) so this lab runs with no internet.

A fixed window counter lets a client send limit requests at 12:00:59 and limit more at 12:01:00: twice the limit in one second. The sliding window log fixes that but stores every timestamp. Day 3, section 2.3 gives the production sweet spot: keep only the count for the current fixed window and the previous one, and weight the previous count by how much of it still overlaps the sliding window.

text4 lines
window      = int(now // window_seconds)        # which fixed window we're in
position    = now % window_seconds              # seconds into it
prev_weight = (window_seconds - position) / window_seconds
estimate    = prev_count * prev_weight + curr_count

Allow the request when estimate < limit, and only then add 1 to curr_count.

Implement SlidingWindowCounterLimiter(limit, window_seconds, clock):

Method Returns
is_allowed(key) True (and counts the request) or False (counts nothing)
estimate(key) the weighted count right now, without counting a request

Rules the tests check:

  • When time moves into the next window, the current count becomes the previous count and the current count starts at 0.
  • When time skips more than one window, the previous count is 0: nothing from two windows ago overlaps.
  • Rejected requests are not counted.
  • Store two counters per key, not timestamps.
  • Read time only through clock.now().

The lesson's worked example (limit 10 per 60 s): at 12:01:15 the previous minute had 8 requests and this minute has 3. The previous window still overlaps 45 of the last 60 seconds, so 8 × 0.75 + 3 = 9 < 10 and the request is allowed.

Python 3.14 loads on first run (~6.5 MB once)14
Loading the editor…
not run yet · 8 s limit
press Run tests

Write your code, then run 2 example tests and 9 hidden tests. Each run is limited to 8 seconds: an infinite loop gets stopped and Python restarts, your code stays.