Skip to main content

Production-ready rate limiting for Go

Five rate limiting algorithms, per-key limits, Redis-backed distributed limiters, and net/http middleware — with a zero-dependency core and concurrency-safe, allocation-free hot paths.

go get github.com/KARTIKrocks/go-ratelimit

Five Algorithms

Token bucket, leaky bucket, fixed window, sliding window log, and sliding window counter

Per-Key Limiting

Independent limits per user, IP, or API key, with idle cleanup and an LRU cap on tracked keys

Distributed with Redis

Atomic Lua scripts, Redis server time, and Cluster-safe keys for limits shared across instances

HTTP Middleware

Drop-in net/http middleware with standard X-RateLimit-* and Retry-After headers

Proxy-Aware Keys

RemoteAddr by default; opt-in X-Forwarded-For handling that only trusts the proxies you list

Fail Open or Closed

Choose what happens when Redis is unreachable, and observe every error through a handler

Composite Limits

Combine per-second, per-minute, and per-hour limits that are checked before any is consumed

Prometheus Metrics

Instrumented wrappers count allowed, denied, and errored checks per named limiter

Zero Dependencies

The core package is stdlib only; Redis and Prometheus live in their own modules

Pick an algorithm

Every algorithm implements the same interfaces, so switching is a one-line change. The trade-off is how much burst you tolerate against how much state you keep per key.

AlgorithmBurstsMemory per keyRedis
Token bucketUp to burst sizeConstantAvailable
Leaky bucketUp to capacityConstantIn-memory only
Fixed windowUp to 2× limit at a boundaryConstantAvailable
Sliding window logUp to limit, exact windowOne timestamp per requestIn-memory only
Sliding window counterApproximate smoothingConstantAvailable

Performance

Measured on an Intel i5-11400H (12 cores), Go 1.27, Linux. Once a key exists, every in-memory limiter decides a request without allocating.

TokenBucket.Allow

50 ns/op

0 allocs, single goroutine

KeyedTokenBucket.Allow

74 ns/op

0 allocs, including the key lookup

Contended Allow

104 ns/op

0 allocs, 12 goroutines on one bucket

SlidingWindowCounter

74 ns/op

0 allocs, single goroutine

Reproduce them yourself with go test -bench=. -benchmem ./... in the repository root. The full benchmark table covers every algorithm and its keyed variant.