-
-
Notifications
You must be signed in to change notification settings - Fork 89
API Rate Limiter
CarterPerez-dev edited this page Feb 11, 2026
·
1 revision
Production-ready rate limiting library for FastAPI with three algorithms, three-layer defense, and advanced client fingerprinting.
fastapi-420 is a rate limiting library implementing sliding window, token bucket, and fixed window algorithms with Redis or in-memory storage. Features a three-layer defense system (per-user, per-endpoint, global DDoS protection), advanced client fingerprinting with IPv6 /64 normalization, and atomic Lua scripts for correctness under concurrent load.
Status: Complete | Difficulty: Advanced
| Technology | Version | Purpose |
|---|---|---|
| Python | 3.12+ | Async/await throughout |
| FastAPI | - | ASGI web framework |
| Redis | 7+ | Distributed storage backend |
| Pydantic | v2 | Settings validation |
| Lua scripts | - | Atomic Redis operations |
| Algorithm | Accuracy | Memory | Best For |
|---|---|---|---|
| Sliding Window | 99.997% | Constant | Production default |
| Token Bucket | Exact | Constant | Burst tolerance |
| Fixed Window | ~Exact | Constant | Simple use cases (has boundary exploit) |
- Per-User Limits — Stop individual abuse
- Per-Endpoint Limits — Prevent endpoint-specific attacks
- Global Limits — DDoS protection with circuit breaker
- IP extraction with proxy-aware
X-Forwarded-Forhandling - IPv6 /64 block normalization (prevents trivial bypass)
- User-Agent and Accept header analysis
- JWT/API key/session identity extraction
- Composite fingerprinting combining all methods
HTTP/1.1 420 Enhance Your Calm
Retry-After: 42
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 1706900000
- GitHub 1.35 Tbps DDoS (2018) — rate limiting enabled 10-minute recovery
- Dunkin' Donuts credential stuffing (2019) — login rate limits block this
- PS5 scalper bots (2020) — checkout rate limits for fair access
Incoming Request
↓
┌─────────────────────────────────────────────┐
│ ASGI Middleware (middleware.py) │
└──────────────────────┬──────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Client Fingerprinting (composite.py) │
│ IP + Headers + Auth → Composite Key │
└──────────────────────┬──────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Three-Layer Defense (layers.py) │
│ User Layer → Endpoint Layer → Global Layer │
└──────────────────────┬──────────────────────┘
↓
┌──────────────┬──────────────┬──────────────┐
│ Sliding │ Token │ Fixed │
│ Window │ Bucket │ Window │
└──────┬───────┴──────┬───────┴──────┬───────┘
└──────────────┼──────────────┘
↓
┌──────────────┬──────────────┐
│ Redis │ In-Memory │
│ Backend │ Backend │
│ (Lua atomic)│ (asyncio) │
└──────────────┴──────────────┘
cd PROJECTS/advanced/api-rate-limiter
# Install dependencies
uv sync
# Optional: Start Redis
docker run -d -p 6379:6379 redis:7-alpine
# Run the example app
uv run python examples/app.py
# Test rate limiting
curl http://localhost:8000/auth/login -X POST -d "username=test&password=test"
# After 3 requests: HTTP/1.1 420 Enhance Your Calm# Redis (production)
REDIS_URL=redis://localhost:6379
# Fallback to in-memory when Redis unavailable
FALLBACK_TO_MEMORY=True
# Trust proxy headers
TRUST_X_FORWARDED_FOR=True
# Circuit breaker threshold
CIRCUIT_THRESHOLD=1000api-rate-limiter/
├── src/fastapi_420/
│ ├── algorithms/ # Rate limiting algorithms
│ │ ├── sliding_window.py
│ │ ├── token_bucket.py
│ │ └── fixed_window.py
│ ├── storage/ # Storage backends
│ │ ├── memory.py # In-memory (single instance)
│ │ ├── redis_backend.py # Redis (distributed)
│ │ └── lua/ # Atomic Lua scripts
│ ├── fingerprinting/ # Client identification
│ │ ├── ip.py # IP + IPv6 /64 normalization
│ │ ├── headers.py # User-Agent, Accept-*
│ │ ├── auth.py # JWT, API keys, sessions
│ │ └── composite.py # Combined fingerprint
│ ├── defense/ # Multi-layer protection
│ │ ├── layers.py # User/Endpoint/Global limits
│ │ └── circuit_breaker.py
│ ├── limiter.py # Main RateLimiter class
│ ├── middleware.py # ASGI middleware
│ ├── dependencies.py # FastAPI dependency injection
│ ├── config.py # Pydantic settings
│ └── types.py # Data structures
├── examples/
│ └── app.py # Full working example
└── tests/
# Run tests
uv run pytest tests/ -v
# Linting
uv run ruff check .
# Type checking
uv run mypy src/
# Format
uv run ruff format .©AngelaMos | CertGames.com | CarterPerez-dev | 2026