| title | description | keywords |
|---|---|---|
Rate Limiting - FastAPI Guard |
Learn how to implement rate limiting in your FastAPI application using FastAPI Guard |
rate limiting, api security, ddos protection, request throttling, fastapi |
Rate limiting is a crucial security feature that protects your API from abuse, DoS attacks, and excessive usage. FastAPI Guard provides a robust rate limiting system through the dedicated RateLimitManager class.
To enable rate limiting, configure the following parameters in your SecurityConfig:
from fastapi import FastAPI
from guard import SecurityMiddleware
from guard.models import SecurityConfig
app = FastAPI()
config = SecurityConfig(
# NOTE: enable_rate_limiting is not required, it's enabled by default
rate_limit=100, # Maximum number of requests allowed
rate_limit_window=60, # Time window in seconds
# ... other configuration options ...
)
app.add_middleware(SecurityMiddleware, config=config)FastAPI Guard implements a sliding window rate limiting algorithm:
- Each client request is tracked using a timestamp
- Only requests within the current time window (last
rate_limit_windowseconds) are counted - When a new request arrives, timestamps older than the window are automatically discarded
- If the count of valid timestamps exceeds
rate_limit, the request is rejected with a 429 status - This ensures precise rate limiting without artificial time boundaries
The sliding window approach offers several advantages over fixed windows:
- No traffic spikes at window boundaries
- More consistent load on your API
- Fair treatment of users across time periods
- More accurate request counting
FastAPI Guard supports two rate limiting storage backends:
By default, rate limiting uses an in-memory deque for tracking request timestamps:
config = SecurityConfig(
# Rate limit is enabled by default
rate_limit=100,
rate_limit_window=60,
enable_redis=False,
)Pros:
- Simple setup (no external dependencies)
- Fast performance
- Automatic cleanup of old timestamps
- True sliding window algorithm
Cons:
- Doesn't work across multiple application instances
- Lost on application restart
- Consumes application memory
For distributed environments, enable Redis-based rate limiting:
config = SecurityConfig(
# NOTE: enable_rate_limiting is not required, it's enabled by default
rate_limit=100,
rate_limit_window=60,
redis_url="redis://localhost:6379/0",
redis_prefix="myapp:" # Optional prefix for Redis keys (override default)
)Pros:
- Works across multiple application instances
- Persists through application restarts
- Uses atomic Lua scripts for reliable concurrency handling
- Consistent rate limiting across distributed systems
Cons:
- Requires a Redis server
- Slightly higher latency due to network calls
- Additional infrastructure dependency
You can customize the rate limit exceeded message:
config = SecurityConfig(
# NOTE: enable_rate_limiting is not required, it's enabled by default
rate_limit=100,
rate_limit_window=60,
custom_error_responses={
429: "Rate limit exceeded. Please try again later."
}
)For advanced use cases, you can access the rate limiter directly:
from guard.handlers.ratelimit_handler import rate_limit_handler
# Get the singleton instance
async def some_route():
# Get a reference to the handler
handler = rate_limit_handler(config)
# Reset rate limits (e.g., for a premium user)
await handler.reset()You might want to reset rate limits in certain scenarios:
from guard.handlers.ratelimit_handler import rate_limit_handler
async def reset_rate_limits_for_user(user_id: str):
handler = rate_limit_handler(config)
# Clear all rate limits (use with caution)
await handler.reset()The RateLimitManager is implemented as a singleton to ensure consistent state across requests. It uses:
- TTLCache for in-memory storage with automatic expiration
- Redis increments with TTL for distributed storage
- Efficient counter storage to minimize memory footprint
- Set reasonable limits: Consider your API's typical usage patterns
- Use Redis in production: For reliability in distributed environments
- Implement graduated limits: Consider different limits for different API endpoints
- Inform clients: Return appropriate headers with rate limit information
- Monitor usage patterns: Keep an eye on rate limit hits to adjust as needed