Rate Limiting Guide
Algorithm Comparison
Token Bucket
Tokens added at constant rate. Requests consume tokens. Allows bursts up to bucket size.
โ Handles bursts, smooth average rate
Leaky Bucket
Requests queue up. Processed at constant rate regardless of input. Very smooth output.
โ Smooth output, no bursts
Fixed Window
N requests allowed per time window (e.g., 100/min). Resets at window boundary. Simple but edge-case burst possible.
โ Simple, easy to understand
Sliding Window
Counts requests in rolling time window. More accurate than fixed window. Higher memory usage.
โ Accurate, no edge burst
Standard Rate Limit Headers
# Response headers (IETF draft standard) RateLimit-Limit: 100 # max requests per window RateLimit-Remaining: 45 # requests left RateLimit-Reset: 1704067200 # Unix timestamp when window resets # When limit exceeded: 429 Too Many Requests HTTP/1.1 429 Too Many Requests Retry-After: 30 # seconds to wait
Redis Token Bucket (Go example)
// Using go-redis with token bucket pattern
func rateLimitCheck(ctx context.Context, rdb *redis.Client, key string, limit int, window time.Duration) bool {
pipe := rdb.Pipeline()
now := time.Now().Unix()
windowStart := now - int64(window.Seconds())
// Remove expired entries
pipe.ZRemRangeByScore(ctx, key, "-inf", strconv.FormatInt(windowStart, 10))
// Count current window
pipe.ZCard(ctx, key)
// Add new request
pipe.ZAdd(ctx, key, &redis.Z{Score: float64(now), Member: now})
pipe.Expire(ctx, key, window)
results, _ := pipe.Exec(ctx)
count := results[1].(*redis.IntCmd).Val()
return count < int64(limit)
}
Recommended Limits by API Type
| API Type | Typical Limit | Notes |
|---|---|---|
| Public read API | 1000/hour | Unauthenticated users |
| Authenticated API | 5000/hour | Per API key |
| Write/mutation API | 100/minute | Per user |
| Login endpoint | 10/minute | Brute force prevention |
| Email/SMS sending | 5/minute | Per user per action |