Rate Limiting and Bot Abuse Protection
Implement distributed rate limiting and throttling with Redis to absorb spikes and block abusive clients.
Why Distributed Rate Limiting
A single FastAPI worker holding a rate-limit counter in process memory breaks the moment you scale horizontally. With N Uvicorn workers behind a load balancer, an abusive client gets N times the allowance because each worker counts independently.
- Goal: one shared counter that every worker and every pod sees.
- Tool: Redis, an atomic in-memory store that all instances connect to.
- Targets: absorb legitimate traffic spikes while throttling or blocking abusive bots.
Throughout this lesson we build the algorithms in plain Python first, then wire them into FastAPI dependencies.
The Fixed Window Counter
The simplest algorithm: divide time into fixed windows (e.g. 60-second buckets) and increment a counter per client per window. When the counter exceeds the limit, reject the request.
Below is a pure-Python simulation so you can see the mechanics without Redis. Notice the boundary problem: a client can send the full quota at the end of one window and again at the start of the next, briefly doubling the effective rate.
import time
class FixedWindow:
def __init__(self, limit, window_seconds):
self.limit = limit
self.window = window_seconds
self.buckets = {}
def allow(self, key, now):
win = int(now // self.window)
bucket_key = (key, win)
count = self.buckets.get(bucket_key, 0) + 1
self.buckets[bucket_key] = count
return count <= self.limit
limiter = FixedWindow(limit=3, window_seconds=60)
base = 1000.0
for i in range(5):
ok = limiter.allow('user:42', base + i)
print(f'request {i+1}: {"ALLOW" if ok else "BLOCK"}')All lessons in this course
- Mitigating the OWASP API Security Top 10
- Rate Limiting and Bot Abuse Protection
- Secrets Management and Key Rotation
- CORS, CSP and Secure Header Policies