A rate limiting library and middleware for Go services. Implements multiple algorithms (token bucket, sliding window, fixed window) backed by Redis for distributed coordination across service instances.
Algorithms Supported
- Token bucket — Smooth rate limiting with burst allowance; good for API gateways
- Sliding window log — Precise, no boundary spikes; higher memory cost per user
- Sliding window counter — Approximate sliding window with O(1) memory; trades precision for efficiency
- Fixed window — Simplest, with known 2x burst at window boundaries
Design
All state lives in Redis. Each algorithm is implemented as an atomic Lua script to avoid race conditions across concurrent check-and-decrement operations. The middleware layer is pluggable — works with net/http, Gin, and Echo.
Design Decisions
- Lua scripts execute atomically on Redis — no need for WATCH/MULTI/EXEC transaction overhead
- Fail-open vs. fail-closed is configurable: default is fail-open to avoid cascading failures
- Keys include a prefix + client identifier (IP, user ID, API key) for flexible granularity
- TTL set to window duration to auto-clean stale keys without a separate GC process
Tradeoffs
Every rate limit check is a Redis round-trip (~0.5–1ms). For high-throughput services this is acceptable. For sub-millisecond requirements, a local approximate counter with periodic Redis sync is a better fit — a pattern used by Cloudflare's rate limiter.