Rate Limiting¶
Per-client rate limiting middleware using a token bucket algorithm.
Package: github.com/oliverandrich/burrow/contrib/ratelimit
Depends on: none
Setup¶
With options:
ratelimit.New(
ratelimit.WithKeyFunc(func(r *http.Request) string {
// Custom key extraction (e.g., API key, user ID)
return r.Header.Get("X-API-Key")
}),
ratelimit.WithOnLimited(func(w http.ResponseWriter, r *http.Request) {
// Custom response for rate-limited requests
http.Error(w, "Slow down!", http.StatusTooManyRequests)
}),
)
How It Works¶
The rate limiter uses a token bucket algorithm from golang.org/x/time/rate:
- Each client (identified by IP or custom key) gets a bucket with
bursttokens - Tokens are refilled at
ratetokens per second - Each request consumes one token
- When the bucket is empty, the request is rejected with HTTP 429 and a
Retry-Afterheader
Idle client entries are automatically cleaned up at the configured interval.
Client Identification¶
By default, the client IP is extracted from RemoteAddr. When --ratelimit-trust-proxy is enabled, the middleware checks X-Forwarded-For and X-Real-IP headers first.
Override with WithKeyFunc() for custom identification (e.g., by API key or authenticated user).
Context Helpers¶
When a request is rate-limited, the Retry-After duration is available in the context:
import "github.com/oliverandrich/burrow/contrib/ratelimit"
retryAfter := ratelimit.RetryAfter(r.Context())
This is useful in custom OnLimited handlers.
Configuration¶
| Flag | Env Var | Default | Description |
|---|---|---|---|
--ratelimit-rate |
RATELIMIT_RATE |
10 |
Requests per second (token refill rate) |
--ratelimit-burst |
RATELIMIT_BURST |
20 |
Maximum burst size (bucket capacity) |
--ratelimit-cleanup-interval |
RATELIMIT_CLEANUP_INTERVAL |
1m |
Interval for sweeping expired entries |
--ratelimit-trust-proxy |
RATELIMIT_TRUST_PROXY |
false |
Use X-Forwarded-For/X-Real-IP for client IP |
Graceful Shutdown¶
The rate limiter implements HasShutdown to stop the background cleanup goroutine when the server shuts down.
Interfaces Implemented¶
| Interface | Description |
|---|---|
burrow.App |
Required: Name(), Register() |
Configurable |
Rate, burst, cleanup interval, and trust-proxy flags |
HasMiddleware |
Rate limiting middleware |
HasShutdown |
Stops the cleanup goroutine |