How to Implement a Rate Limiter in Python
A beginner-friendly Python class that tracks call timestamps with a deque to allow or block calls based on a max rate per time period.
Python code
31 linesimport time
from collections import deque
class RateLimiter:
"""Simple rate limiter for beginners."""
def __init__(self, max_calls: int, period_seconds: float):
self.max_calls = max_calls
self.period = period_seconds
self.calls = deque()
def allow(self) -> bool:
"""Return True if a call is allowed, False otherwise."""
now = time.monotonic()
while self.calls and now - self.calls[0] >= self.period:
self.calls.popleft()
if len(self.calls) < self.max_calls:
self.calls.append(now)
return True
return False
if __name__ == "__main__":
limiter = RateLimiter(max_calls=3, period_seconds=1.0)
for i in range(5):
print(f"Call {i + 1}: {'allowed' if limiter.allow() else 'blocked'}")
time.sleep(1.0)
print("After 1 second:")
print(f"Call 6: {'allowed' if limiter.allow() else 'blocked'}")
Output
Call 1: allowed
Call 2: allowed
Call 3: allowed
Call 4: blocked
Call 5: blocked
After 1 second:
Call 6: allowed
How it works
The RateLimiter uses a deque to store timestamps of recent calls. time.monotonic() gives a stable clock that never jumps, so rate limiting stays accurate. On each allow() check, it removes timestamps older than the period, then checks if the current count is below the limit. If so, it records the current time and returns True; otherwise, it returns False. This sliding-window approach is simple, memory‑efficient, and works for any rate limit pattern in small applications.
Common mistakes
- Using `time.time()` instead of `time.monotonic()` — wall clock changes can break the limiter.
- Forgetting that `deque` is not thread‑safe — for concurrent use, wrap calls with a lock.
- Not pruning old timestamps, causing memory growth and inaccurate counts.
Variations
- Use a fixed‑window counter with a start timestamp and reset when the window expires.
- Use a token bucket algorithm with a background refill for smoother burst control.
Real-world use cases
- Limiting API requests from a CLI script so you respect a third‑party rate limit.
- Throttling user actions in a web app to prevent spam, e.g., login attempts or form submissions.
- Capping the number of external calls a background worker makes per second to avoid overloading a downstream service.
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.