Overview
This responder is unique because it continues the handler chain rather than terminating the request. It sets anX-RateLimit-Apply header on requests from matching IP ranges, which caddy-ratelimit can then use to apply different rate limits to different client groups.
Requirements
Configuration
IP ranges to mark for rate limiting. Can be CIDR notations or predefined service keys.Default:
["aws", "azurepubliccloud", "deepseek", "gcloud", "githubcopilot", "openai"]Optional list of specific IP addresses to exclude from rate limiting.Default:
[]Behavior
When a request matches the configured ranges:Set to
"true" on matching requestsContinues to next handler in chain (does not terminate)
Examples
Implementation Details
The Rate Limit responder is implemented inresponders/ratelimit.go:12:
- Modifies the request by adding a header
- Calls
next.ServeHTTP()to continue the handler chain - Does not terminate the request
How It Works
caddy-ratelimit Integration
The caddy-ratelimit module checks for the header:Rate Limit Parameters
- events - Number of requests allowed
- window - Time window for the limit (e.g.,
1m,1h) - key - What to rate limit by (IP, path, header, etc.)
Use Cases
Tiered Rate Limiting
Apply different limits to different client groups:API Endpoint Protection
Rate limit API endpoints from AI scrapers:Cost Control
Limit expensive operations for suspected scrapers:Advantages
- Flexible - Doesn’t block, just marks requests for rate limiting
- Targeted - Apply different limits to different IP ranges
- Graceful - Allows some access, just rate-limited
- Customizable - Full control over rate limit policies
- Non-blocking - Legitimate traffic not completely blocked
Comparison with Other Responders
- vs Block: Rate Limit allows some requests, Block denies all
- vs Drop: Rate Limit continues chain, Drop terminates
- vs Tarpit: Rate Limit uses module, Tarpit slows directly
- vs Custom: Rate Limit marks requests, Custom returns response
Best Practices
- Order matters - Place
defenderbeforerate_limitin handler order - Set reasonable limits - Don’t make limits too strict
- Monitor logs - Check what’s being rate limited
- Use multiple zones - Different limits for different scenarios
- Consider whitelist - Protect known good IPs from limits
Handler Order
Testing
Test rate limiting:Troubleshooting
Rate limiting not working
- Check handler order - Ensure defender comes before rate_limit
- Verify header match - Confirm rate_limit is matching the header
- Check IP ranges - Verify the client IP is in configured ranges
- Review rate_limit config - Ensure caddy-ratelimit is properly configured
All requests being rate limited
- Check ranges - May be too broad (e.g., using
all) - Verify whitelist - Add known good IPs to whitelist
- Review rate_limit zones - May have multiple zones matching
Advanced Examples
Combined with Other Responders
Custom Rate Limit Response
Related Documentation
- caddy-ratelimit Documentation - Full rate limiting module docs
- Block Responder - For complete blocking instead
- Tarpit Responder - For slowing down responses
- Handler Order - Caddy handler ordering