Overview
Coraza Proxy includes built-in per-IP rate limiting using the token bucket algorithm. This protects your backend services from abuse and ensures fair resource distribution across clients.Environment Variables
Maximum number of requests per second allowed per IP address.
Maximum burst size - the number of requests that can be made in a short burst above the rate limit.
How It Works
Data Structures
The rate limiter uses these structures (frommain.go:29-40):
Initialization
The rate limiter is created at startup (frommain.go:55-64):
main.go:412-415):
Per-IP Limiter
Each IP address gets its own rate limiter (frommain.go:66-81):
Automatic Cleanup
Inactive IP addresses are removed from memory (frommain.go:83-95):
Request Handling
Each request is checked against the rate limiter (frommain.go:441-445):
Client IP Detection
The real client IP is extracted from headers or remote address (frommain.go:249-262):
Token Bucket Algorithm
The rate limiter uses the token bucket algorithm:- Each IP gets a bucket that holds tokens
- Tokens are added to the bucket at the rate defined by
PROXY_RATE_LIMIT - The bucket can hold up to
PROXY_RATE_BURSTtokens - Each request consumes one token
- If no tokens are available, the request is rejected with HTTP 429
Example Calculation
With default settings (PROXY_RATE_LIMIT=5, PROXY_RATE_BURST=10):
- Sustained rate: 5 requests per second
- Burst capacity: Can make 10 requests instantly
- Recovery: Bucket refills at 5 tokens/second
- User makes 10 requests instantly → All succeed (burst consumed)
- User makes 1 more request immediately → Rejected (no tokens)
- After 0.2 seconds → 1 token available
- After 1 second → 5 tokens available
- After 2 seconds → Bucket full again (10 tokens)
Configuration Examples
Strict Rate Limiting
Lenient Rate Limiting
API Usage
Development Mode
Docker Compose Example
Response Headers
When a client is rate limited, they receive:Monitoring
Rate limit events are logged:- Detect potential DDoS attacks
- Identify problematic clients
- Tune rate limit parameters
- Analyze traffic patterns
Behind Cloudflare or Load Balancers
The rate limiter correctly identifies client IPs when behind proxies:- Cloudflare: Uses
CF-Connecting-IPheader - Load Balancers: Uses
X-Forwarded-Forheader (first IP) - Direct Connection: Uses
RemoteAddr
Memory Management
- Each IP address consumes approximately 200 bytes of memory
- Inactive IPs are removed after 3 minutes
- The cleanup goroutine runs every minute
- Thread-safe with mutex protection
- Memory usage: ~2 MB
- After 3 minutes of inactivity: Memory freed
Best Practices
- Start conservative: Begin with lower limits and increase as needed
- Monitor logs: Watch for legitimate users hitting limits
- Consider use case: APIs need different limits than websites
- Burst size: Set burst to 2x the rate limit for normal traffic spikes
- Combine with WAF: Rate limiting complements WAF protection
- Test your limits: Use load testing to verify settings work for your traffic
Limitations
- Rate limits are per-proxy instance (not shared across multiple instances)
- For distributed rate limiting, consider using Redis or a similar solution
- The current implementation doesn’t support whitelisting specific IPs
Performance Impact
The rate limiter is highly efficient:- O(1) lookup for existing IPs
- Minimal CPU overhead per request
- Automatic memory cleanup
- Thread-safe concurrent access
