Rate Limiting for Self-Hosted Apps: Protect Your Infrastructure
Rate limiting prevents abuse by restricting how many requests a client can make. Essential for any self-hosted app exposed to the internet.
Why Rate Limit?
Without rate limiting, a single client can:
Types of Rate Limiting
Fixed Window
Allow N requests per time window (e.g., 100 requests per minute). Simple but can allow bursts at window boundaries.
Sliding Window
Smooth rate limiting that tracks requests over a rolling window. More accurate than fixed window.
Token Bucket
Tokens are added at a fixed rate. Each request consumes a token. Allows short bursts while maintaining an average rate.
Leaky Bucket
Requests flow through at a fixed rate. Excess requests are queued or dropped. Smoothest output rate.
Where to Rate Limit
Reverse Proxy Level
First line of defense. Rate limit at Caddy/Nginx before requests reach your app.
#### Caddy
Caddy has rate limiting available via plugins. Configure per-IP limits.
#### Nginx
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api {
limit_req zone=api burst=20;
}
Application Level
More granular control. Rate limit by user account, API key, or endpoint.
Framework middleware:
API Gateway
For complex setups, use a dedicated API gateway (Kong, Tyk) for centralized rate limiting.
What to Rate Limit
Login Pages
5-10 attempts per minute per IP. Prevents brute force attacks.
API Endpoints
100-1000 requests per minute per API key. Depends on your application.
File Uploads
Limit upload frequency and size. Prevent storage abuse.
Password Reset
3-5 requests per hour per email. Prevents email flooding.
Response to Rate Limiting
Return HTTP 429 Too Many Requests with:
Cloudflare Rate Limiting
If your app is behind Cloudflare, use their rate limiting rules (free tier includes basic rules). Rate limiting at the edge stops abuse before it reaches your server.