All versions since v1.0.1
v1.0.1
🚀 What’s New in v1.0.1
We are excited to announce the first official production release of distlimit!
distlimit is a high-performance, enterprise-grade rate limiter for Go designed for extreme throughput and zero-downtime resilience.
✨ Key Features
- Zero-Dependency Core: Built purely on Go’s standard library.
- Lock-Free In-Memory Engine: Built with
sync/atomic(Compare-And-Swap) for nanosecond latency and 0 B/op memory allocation. - Atomic Redis Lua Scripting: Implements Sliding Window Log executed in a single network round-trip.
- Graceful Redis Fallback: Automatically degrades evaluation to local memory if Redis goes down.
- Circuit Breaker Cool-Off: Prevents overwhelming a recovering Redis server during outages.
- IETF Standard RateLimit Headers: Automatically injects
RateLimit-Limit,RateLimit-Remaining,RateLimit-Reset, andRetry-After. - Ready-to-use Middleware: Includes plug-and-play adapters for
net/httpandGin Gonic.
📦 Installation
go get [github.com/balramadan/distlimit@v1.0.0](https://github.com/balramadan/distlimit@v1.0.1)📖 Documentation & Examples
Check out the full documentation and runnable examples in the repository’s README.md or visit pkg.go.dev
v1.1.0
⚡ distlimit v1.1.0 — Pluggable Architecture & Enterprise Security Hardening
We are thrilled to announce the official release of distlimit v1.1.0! This milestone update transforms distlimit into a fully modular, enterprise-grade distributed rate limiter for Go, featuring pluggable strategy algorithms, security-hardened middlewares, 64-sharded memory management, and dual-tier circuit breaker resilience.
🔌 1. Pluggable Strategy Architecture
- 5 Standard Algorithms Included:
- Token Bucket: Burst-friendly rate limiting.
- Leaky Bucket: Smooth traffic shaping for third-party integrations.
- Fixed Window: Ultra-fast counter reset protection.
- Sliding Window Log: 100% exact precision for strict quotas.
- Sliding Window Counter: $O(1)$ memory weighted moving average precision.
- 100% Backward Compatible: Existing
v1.0.0users can upgrade seamlessly without breaking API changes via Go type aliases and automatic default fallback algorithm configurations.
🛡️ 2. Security & QA Audit Remediation (P0 & P1 Fixes)
Following a comprehensive QA & Security Engineering audit, the following critical issues have been remediated and verified:
- [P0 - Security] Anti-IP Spoofing Shield:
- Native CIDR-validated
WithTrustedProxiesinspection implemented across all HTTP (net/http,gin,echo,fiber) andgRPCmiddleware adapters. - Headers
X-Forwarded-ForandX-Real-IPare strictly ignored unless the direct connection (RemoteAddr/PeerAddr) originates from a verified trusted proxy subnet.
- Native CIDR-validated
- [P0 - Redis Cluster] CROSSSLOT Compatibility:
- Wrapped key generation with Redis Hash Tags
{}(distlimit:{key}) indriver/redis. - Guarantees that dynamic window/sequence keys land on the exact same Redis Hash Slot in clustered environments, preventing
CROSSSLOTexecution errors.
- Wrapped key generation with Redis Hash Tags
- [P0 - Race Condition] Atomic ZSET Member Uniqueness:
- Integrated an atomic Redis
INCRsequence generator (key .. ":seq") in the Sliding Window Log Lua. - Eliminates member overwrites during high-concurrency requests landing on the exact same millisecond score.
- Integrated an atomic Redis
- [P1 - Memory] 64-Sharded In-Memory Map Architecture:
- Converted
driver/memoryto a 64-sharded lock architecture using FNV-1a key hashing. - Eliminates global mutex lock contention during high-throughput requests and background cleanup runs.
- Converted
- [P1 - Memory] Heap Retention Truncation:
- Added active slice re-allocation buffer logic in
slidinglogin-memory state when array capacity waste exceeds 50%. - Prevents gradual RAM bloat and allows Go Garbage Collector to reclaim unused memory.
- Added active slice re-allocation buffer logic in
- [P1 - Resilience] Half-Open Circuit Breaker Probing:
- Implemented an atomic
CAS(Compare-And-Swap) single-request probing mechanism indriver/hybrid. - Prevents Thundering Herd request stampedes against Redis during recovery after an outage cool-off period.
- Implemented an atomic
- [P2 - Context] Context Cancellation Check:
- Added early
select <-ctx.Done()checks in the in-memory driver to avoid mutating state if the caller’s request context was canceled.
- Added early
🌐 3. Framework Middlewares & Runnable Examples
Complete, production-ready middleware adapters and runnable examples included in examples/:
- ⚡ Fiber v3 (
middleware/fiber,examples/fiber-slidingcounter) - 🍸 Gin Framework (
middleware/gin,examples/gin-hybrid) - 🔊 Echo v4 & v5 (
middleware/echo,middleware/echov5,examples/echo,examples/echov5) - 🌐 Standard net/http & Chi (
middleware/nethttp,examples/nethttp) - 📡 gRPC Unary & Streaming Interceptors (
middleware/grpc,examples/grpc)
📊 4. Performance & Benchmarks
Benchmarked on AMD 3020e Linux x86_64:
| Algorithm | Performance | Memory Overhead | Allocations |
|---|---|---|---|
| Sliding Log | 20.36 ns/op |
0 B/op | 0 allocs/op |
| Token Bucket | 46.18 ns/op |
0 B/op | 0 allocs/op |
| Leaky Bucket | 47.76 ns/op |
0 B/op | 0 allocs/op |
| Fixed Window | 77.27 ns/op |
0 B/op | 0 allocs/op |
| Sliding Counter | 129.10 ns/op |
0 B/op | 0 allocs/op |
🚀 5. Installation & Upgrade
To update your Go project to v1.1.0:
go get github.com/balramadan/distlimit@v1.1.0What’s Changed
- Release/v1.1.0 by @balramadan in https://github.com/balramadan/distlimit/pull/1
New Contributors
- @balramadan made their first contribution in https://github.com/balramadan/distlimit/pull/1
Full Changelog: https://github.com/balramadan/distlimit/compare/v1.0.1...v1.1.0
v1.1.1
🐛 Bug Fixes
- Fixed Header Value Formatting in nethttp Middleware
- Issue: The nethttp middleware previously formatted rate limit header values using http.StatusText() instead of stringifying numerical values. This resulted in improper header values such as X-RateLimit-Limit: OK.
- Fix: Replaced http.StatusText() with strconv.FormatInt(). Header values now correctly output formatted numeric strings (e.g., X-RateLimit-Limit: 100).
- Resolved Failover Race Condition in hybrid Driver
- Issue: Under high concurrent loads during primary driver outages, multiple goroutines could simultaneously trigger the onError callback and update lastFailUnix timestamps.
- Fix: Converted the isDown state transition to use atomic CompareAndSwap(false, true). Now, exactly one goroutine executes the circuit breaker transition and triggers the error callback per failure event.
- Added Guard Against nil Functions in WithKeyFunc
- Issue: Passing WithKeyFunc(nil) explicitly during distlimit.New() initialization cleared the default key extraction function, leading to potential nil pointer dereference panics during Allow().
- Fix: Added a nil check in WithKeyFunc(). If a nil function is provided, the Limiter safely preserves the default key extraction logic (“global”)
✨ New Features & Enhancements
- Manual Rate Limit Reset API (ResetKey & Driver.Reset)
- Introduced Limiter.ResetKey(ctx context.Context, key string) error allowing operators to manually reset the rate limit counter for a specific key (e.g., following successful CAPTCHA verification or administrator action).
- Added Reset(ctx context.Context, key string) error method to the Driver interface, implemented across all standard drivers:
- Memory Driver: Removes state entries directly from the designated hash shard.
- Redis Driver: Deletes the key and its corresponding sequence tracking key atomically in Redis.
- Hybrid Driver: Delegates reset operations to both the primary and fallback storage drivers.
- RFC 6585 & IETF Draft Header Standardization
- All HTTP framework middleware adapters (nethttp, gin, echo, echov5, fiber) now inject standard IETF RFC 6585 headers alongside legacy X-RateLimit-* headers for backward compatibility:
- RateLimit-Limit: Maximum capacity for the window.
- RateLimit-Remaining: Remaining quota in the current window.
- RateLimit-Reset: Time remaining in seconds until window reset.
- Fallback Handling for Empty Keys
- Updated Allow(), AllowKey(), and ResetKey() to automatically convert empty key strings (“”) to “global” to prevent key collisions across empty extractions.
📦 Upgrade Guide
To update your project to v1.1.1, run:
go get -u github.com/balramadan/distlimit@v1.1.1What’s Changed
- Hotfix/v1.1.1 by @balramadan in https://github.com/balramadan/distlimit/pull/2
Full Changelog: https://github.com/balramadan/distlimit/compare/v1.1.0...v1.1.1
v1.2.0 Latest
✨ New Features & Enhancements
1. Pluggable Observability & Telemetry Engine (metrics/)
- Core Observer Interface: Introduced
metrics.Observerinterface andmetrics.Eventsnapshot data structure. - Zero-Allocation Guarantee: Evaluated at $0\text{ B/op}$ and $0\text{ allocs/op}$ when telemetry observers are disabled.
- Prometheus Support (
metrics/prometheus): Native collectors for evaluation counts (distlimit_requests_total), execution latency histograms (distlimit_evaluation_duration_seconds), and hybrid failovers (distlimit_hybrid_fallback_total). - OpenTelemetry Support (
metrics/otel): Turnkey OTel MeterProvider integration (Int64Counter&Float64Histogram).
2. Lock-Free Dynamic Policy & Runtime Reload Engine
- Atomic Policy Swapping:
Limiterinternal state refactored toatomic.Pointer[Policy]. Callinglimiter.UpdatePolicy(limit, window)updates limits instantly with zero lock contention ($O(1)$ zero lock delay). - Multi-Tenant
PolicyResolver: AddedPolicyResolverinterface allowing dynamic tier-based rate limit rules per key (e.g., VIP vs Free tiers) viaWithPolicyResolver().
3. Middleware Route Labeling (WithRouteLabeling)
- Context helper utilities
ContextWithRoute(ctx, route)andRouteFromContext(ctx). - Added
WithRouteLabeling(true)option across all middleware adapters (net/http,Gin,Echo v4,Echo v5,Fiber v3, andgRPC). This passes parametrized route patterns (e.g./api/v1/users/:idor gRPCFullMethod) directly into metric labels.
📂 Working Examples
- Prometheus Instrumentation Example:
examples/prometheus-metrics/main.go - Dynamic Policy & Resolver Example:
examples/dynamic-policy/main.go
What’s Changed
- feat: observability & telemetry engine, dynamic policy & runtime relo… by @balramadan in https://github.com/balramadan/distlimit/pull/3
- Release/v1.2.0 by @balramadan in https://github.com/balramadan/distlimit/pull/4
Full Changelog: https://github.com/balramadan/distlimit/compare/v1.1.1...v1.2.0