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.
Python code
40 linesfrom 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
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
- Use `time.monotonic()` instead of `datetime.utcnow()` for wall-clock-independent timing.
- 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
More from Reliability & rate limiting
- At Least Once with Idempotent Consumer in Python medium
- Build a Rate Limiter Decorator in Python easy
- Build a queue-based admission control system in Python easy
- Chaos Inject Random Failures in Python easy
- Circuit breaker failure threshold count in Python medium
- Exactly Once Processing Dedupe Mock in Python easy
Keep learning
Related tutorials and quizzes for this topic.