Free preview

Sliding Window Log and Sliding Window Counter

In one line: these two fix the boundary bug, and they sit at opposite ends of the same trade. The weighted formula in the second one is the only real arithmetic in this chapter — worth being able to do live.

Sliding window log

Limit: 2 requests per minute.   Window always ends "now".

now = 01:30    log = [01:00, 01:15]        -> 2 entries, at limit
               new request at 01:30        -> REJECTED

now = 02:05    drop anything before 01:05
               log = [01:15]               -> 1 entry
               new request at 02:05        -> ACCEPTED
               log = [01:15, 02:05]
ParameterMeaning
Log size (L)The maximum number of requests allowed in the time frame (similar to R)
Arrival time (T)The timestamp of the incoming request
Time range (T_r)The duration of the window. Timestamps outside this range are discarded
Detail
AdvantagesAccurate rate limiting without boundary issues
DisadvantagesHigh memory consumption because it stores timestamps for every request, even those rejected

Why there is no boundary to exploit

Fixed window has a boundary because the counter resets at a fixed instant. Sliding window log has no such instant — the window is always the last T_r seconds ending right now, so it moves continuously with every request.

There is no moment to fire a burst "just before the reset," because there is no reset. Every evaluation looks back exactly one window from the present.

This is exact enforcement in the strongest sense: at no point in time can more than L requests exist in any window of length T_r. That is a stronger guarantee than anything else in this chapter, and it is what you pay memory for.

'Even those rejected' is the detail that makes this expensive

The disadvantage is worth reading carefully. The log stores a timestamp for every request, including rejected ones — which means an abusive client generates the most state.

Sit with the inversion: the algorithm's memory cost is proportional to attack volume. A client hammering you at 10,000 requests/second while limited to 10/second causes 10,000 timestamps per second of storage, and every one of those requests is being rejected. The rate limiter becomes a memory amplifier for exactly the traffic it is rejecting.

That is a genuine denial-of-service vector against the limiter itself, and it is why sliding window log is rarely used unmodified at scale. Mitigations: cap the log length regardless of arrival rate, or stop recording once the limit is exceeded — though that weakens the exactness guarantee you paid for.

Being able to name this as an attack surface rather than just "uses more memory" is a strong senior observation.

Sliding window counter

Key takeaway

A hybrid approach. It combines the fixed-window counter and sliding-window log algorithms to smooth traffic flow without the high memory cost of storing individual timestamps.

The formula:

Rate = R_p x (time frame - overlap time) / time frame  +  R_c

  R_p          = previous window count
  R_c          = current window count
  time frame   = window size
  overlap time = time elapsed in the current window

Worked example

Rate limit 100 requests per minute. The previous window had 88 requests, the current window has 12. A new request arrives at 02:15, which is 15 seconds (25%) into the current window.

R_p = 88,  R_c = 12,  time frame = 60 s,  overlap time = 15 s

Rate = 88 x (60 - 15) / 60 + 12
     = 88 x 45 / 60 + 12
     = 88 x 0.75 + 12
     = 66 + 12
     = 78

78 < 100  ->  the request is ACCEPTED
ParameterMeaning
Rate limit (R)The maximum requests allowed per window
Window size (W)The duration of the time window
Previous window count (R_p)Total requests in the previous window
Current window count (R_c)Total requests in the current window
Overlap time (O_t)The time elapsed in the current window
Detail
AdvantagesMemory efficient due to limited state requirements · smooths traffic bursts using a weighted average of the previous window
DisadvantagesAssumes requests in the previous window were evenly distributed, which is an approximation

Read the weight as 'how much of the previous window is still in view'

The factor (time frame − overlap time) / time frame is just the fraction of the sliding window that still overlaps the previous fixed window.

At 15 seconds into the current minute, the last 60 seconds consist of 15 seconds of the current window and 45 seconds of the previous one — so 45/60 = 75% of the previous window is still in view, and you count 75% of its requests.

As time advances the weight decays smoothly: at 30 s it is 50%, at 45 s it is 25%, at 60 s it is 0 and the previous window has scrolled out entirely.

That decay is what removes the boundary bug. There is no instant where the old count vanishes — it fades, so a burst at 01:59 keeps counting against you well into the next minute rather than being forgotten at the stroke of 02:00.

The even-distribution assumption is where it can be wrong — in both directions

The algorithm has two numbers for the previous window: how many requests, and nothing about when. So it assumes they were spread evenly.

When they were actually clustered at the start of the previous window, they have really scrolled out of view — but the formula still charges you 75% of them. Legitimate requests get rejected.

When they were clustered at the end, they are all genuinely still in the window — but the formula only counts 75%. Excess requests get allowed.

So the error goes both ways, bounded by how skewed the previous window was. Cloudflare published data showing this approximation is accurate to well under 1% of requests in practice, which is why it is widely deployed despite being technically wrong.

The right framing for an interview: it trades exactness for O(1) state, and the error is small because real traffic is rarely maximally skewed. That is a much better answer than "it's approximate."

Two counters, not thousands of timestamps

The state is the previous window's count, the current window's count, and the current window's start — a handful of integers per client, regardless of traffic volume.

Compare sliding window log, whose state grows with every request including rejected ones. The hybrid gets almost all of the boundary-fixing benefit for a constant amount of memory, and crucially its memory cost does not scale with attack volume.

That is why sliding window counter is the algorithm most large CDNs and API gateways actually run: it is the only one that fixes the boundary problem without handing attackers a memory amplifier.

Key takeaway

Sliding window log is exactly correct with no boundary to exploit, but stores a timestamp per request including rejected ones — memory proportional to attack volume. Sliding window counter weights the previous window by how much of it is still in view, fixing the boundary with constant state, at the cost of assuming even distribution within that window.

Interview signal by level

LevelWhat a strong answer sounds like
L4"Sliding window keeps a moving window instead of a fixed one."
L5Explains both and the trade: "the log stores every timestamp so it's exact but memory-hungry; the counter weights the previous window's count by how much of it still overlaps, so it's approximate but constant state."
Staff+Runs the arithmetic and names the attack surface: "at 15 seconds in, 45 of the last 60 seconds are the previous window, so you count 75% of it — 88 times 0.75 plus 12 is 78, under 100, allow. The approximation errs both ways depending on skew, but it's well under 1% in practice. And I'd avoid the log at scale: it stores a timestamp for rejected requests too, so its memory scales with attack volume — the attacker is filling your store by being rejected."

Next: choosing between all five.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue