How to Implement a Sliding Window Log Rate Limiter in Python

Implements a sliding window log rate limiter in Python using a deque of timestamps to enforce a maximum request count within a rolling time window.

Medium Python 3.9+ Aug 9, 2026 Reliability & rate limiting 15 views 0 copies

Python code

40 lines
Python 3.9+
from collections import deque
from datetime import datetime, timedelta
from time import sleep


class SlidingWindowLog:
    def __init__(self, window_seconds: int, max_requests: int):
        self.window_seconds = window_seconds
        self.max_requests = max_requests
        self.timestamps = deque()

    def allow_request(self) -> bool:
        now = datetime.utcnow()
        cutoff = now - timedelta(seconds=self.window_seconds)

        while self.timestamps and self.timestamps[0] < cutoff:
            self.timestamps.popleft()

        if len(self.timestamps) < self.max_requests:
            self.timestamps.append(now)
            return True
        return False

    def get_timestamps(self) -> list:
        return list(self.timestamps)


if __name__ == "__main__":
    log = SlidingWindowLog(window_seconds=3, max_requests=2)

    print(log.allow_request())   # True
    sleep(0.1)
    print(log.allow_request())   # True
    sleep(0.1)
    print(log.allow_request())   # False (window full)

    sleep(3.5)                   # wait for window to expire

    print(log.allow_request())   # True (old timestamps evicted)
    print(log.get_timestamps())  # show current window contents

Output

stdout
True
True
False
True
[datetime.datetime(2025, 1, 1, 12, 0, 3, 500000)]

How it works

The SlidingWindowLog class uses a deque to store timestamps of recent requests. On each call to allow_request, it prunes expired timestamps (older than the window) from the front, then checks if the remaining count is below the limit. If so, it appends the current timestamp and returns True; otherwise it returns False. The get_timestamps method returns a snapshot of the current window contents for debugging or monitoring.

Common mistakes

  • Using `time.sleep` for window expiry in production instead of relying on timestamp math — sleep blocks the thread.
  • Forgetting to prune expired timestamps before checking the count, causing false denials.
  • Using an unbounded list instead of a deque — appends at the front of a list are O(n).

Variations

  1. Use `time.monotonic()` instead of `datetime.utcnow()` for wall-clock-independent timing.
  2. Store timestamps as epoch seconds (floats) to reduce overhead in high-throughput systems.

Real-world use cases

  • Limiting API endpoints per user to prevent abuse in production web services.
  • Throttling outbound requests to third-party services with strict call quotas.
  • Enforcing login attempt limits per IP address to slow brute-force attacks.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Reliability & rate limiting

Related tutorials and quizzes for this topic.