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 TypeTypical LimitNotes
Public read API1000/hourUnauthenticated users
Authenticated API5000/hourPer API key
Write/mutation API100/minutePer user
Login endpoint10/minuteBrute force prevention
Email/SMS sending5/minutePer user per action