- Docs
- Security
- Rate limiting
Rate limiting
Bound request rates per key with token buckets in memory or shared over Redis.
ratelimit bounds how fast one key (user, IP, token) can use an endpoint. Limiter.Allow returns a Decision with Allowed, RetryAfter, and Remaining; mapping a denial to 429 and the fail mode are your call.
Quick start
Section titled “Quick start”The default is memory with rate: 10, burst: 20. rate (refill per second) and burst (bucket size) are both required, over zero, and finite.
RATELIMIT_ADAPTER=memoryRATELIMIT_RATE=10RATELIMIT_BURST=20rl, err := c.RateLimit() // c.Ratelimit() is an aliasif err != nil { return err}defer rl.Close()for i := 0; i < 3; i++ { dec, err := rl.Allow(ctx, "book:guest-1", 1) fmt.Println(dec.Allowed, dec.Remaining, err)}true 19 <nil>true 18 <nil>true 17 <nil>Limit a request path
Section titled “Limit a request path”The bookings handler calls Allow(ctx, "book:"+guest, 1), returns 429 when !dec.Allowed, and 500 on error. Charges cap at burst. Generated servers wire middleware.RateLimit (HTTP 429 + Retry-After) and a gRPC interceptor (ResourceExhausted) when RATELIMIT_ADAPTER is set; both fail open, and WithFailMode(FailClosed) opts in.
Share limits across replicas
Section titled “Share limits across replicas”Per-instance buckets multiply the effective limit (limit x replica count); switch to redis once more than one replica serves traffic.
RATELIMIT_ADAPTER=redisRATELIMIT_RATE=100RATELIMIT_BURST=200RATELIMIT_REDIS_ADDR=127.0.0.1:6379RATELIMIT_REDIS_PREFIX=rl:RATELIMIT_ADAPTER=redisRATELIMIT_RATE=100RATELIMIT_BURST=200Use a distinct redis.prefix per environment. File durations are integer nanoseconds (idle_ttl default 10m, sweep_interval 1m); env accepts "5s". Validate rejects non-positive rate/burst, negative idle_ttl/sweep_interval, and bad Redis addr/prefix. Adapters: ratelimit/memory (default) and ratelimit/redis. Keys: reference.
Production checklist
Section titled “Production checklist”Limiter.Close() errortakes no context; the container joins errors witherrors.Join, and panics become*ClosePanicError.- Keys can be PII (IP, user ID);
InvalidKeyErrorreports only length. - Never log raw option maps; use
cfg.RedactedServices().
Troubleshooting
Section titled “Troubleshooting”The effective limit looks multiplied
Replicas run memory buckets; move to redis, or divide the per-instance rate by the replica count.
rate must be > 0 and finite
rate and burst are required; an empty options block fails Validate (the bookings example uses RATELIMIT_RATE=10, RATELIMIT_BURST=20 in .env).
InvalidKeyError on Allow
Keys cap at 256 bytes (MaxKeyLen) with no control bytes; hash or truncate long composite keys first.