Skip to content

API Rate Limiter

CarterPerez-dev edited this page Feb 11, 2026 · 1 revision

API Rate Limiter

Production-ready rate limiting library for FastAPI with three algorithms, three-layer defense, and advanced client fingerprinting.

Overview

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

Tech Stack

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

Features

Rate Limiting Algorithms

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)

Three-Layer Defense

  1. Per-User Limits — Stop individual abuse
  2. Per-Endpoint Limits — Prevent endpoint-specific attacks
  3. Global Limits — DDoS protection with circuit breaker

Client Fingerprinting

  • IP extraction with proxy-aware X-Forwarded-For handling
  • IPv6 /64 block normalization (prevents trivial bypass)
  • User-Agent and Accept header analysis
  • JWT/API key/session identity extraction
  • Composite fingerprinting combining all methods

Response Headers

HTTP/1.1 420 Enhance Your Calm
Retry-After: 42
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 1706900000

Security Relevance

  • 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

Architecture

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)   │
└──────────────┴──────────────┘

Quick Start

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

Configuration

# 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=1000

Project Structure

api-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/

Development

# Run tests
uv run pytest tests/ -v

# Linting
uv run ruff check .

# Type checking
uv run mypy src/

# Format
uv run ruff format .

Source Code

View on GitHub

Clone this wiki locally