Lewati ke konten

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, and Retry-After.
  • Ready-to-use Middleware: Includes plug-and-play adapters for net/http and Gin Gonic.

📦 Installation

Terminal window
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.0 users 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 WithTrustedProxies inspection implemented across all HTTP (net/http, gin, echo, fiber) and gRPC middleware adapters.
    • Headers X-Forwarded-For and X-Real-IP are strictly ignored unless the direct connection (RemoteAddr/PeerAddr) originates from a verified trusted proxy subnet.
  • [P0 - Redis Cluster] CROSSSLOT Compatibility:
    • Wrapped key generation with Redis Hash Tags {} (distlimit:{key}) in driver/redis.
    • Guarantees that dynamic window/sequence keys land on the exact same Redis Hash Slot in clustered environments, preventing CROSSSLOT execution errors.
  • [P0 - Race Condition] Atomic ZSET Member Uniqueness:
    • Integrated an atomic Redis INCR sequence generator (key .. ":seq") in the Sliding Window Log Lua.
    • Eliminates member overwrites during high-concurrency requests landing on the exact same millisecond score.
  • [P1 - Memory] 64-Sharded In-Memory Map Architecture:
    • Converted driver/memory to a 64-sharded lock architecture using FNV-1a key hashing.
    • Eliminates global mutex lock contention during high-throughput requests and background cleanup runs.
  • [P1 - Memory] Heap Retention Truncation:
    • Added active slice re-allocation buffer logic in slidinglog in-memory state when array capacity waste exceeds 50%.
    • Prevents gradual RAM bloat and allows Go Garbage Collector to reclaim unused memory.
  • [P1 - Resilience] Half-Open Circuit Breaker Probing:
    • Implemented an atomic CAS (Compare-And-Swap) single-request probing mechanism in driver/hybrid.
    • Prevents Thundering Herd request stampedes against Redis during recovery after an outage cool-off period.
  • [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.

🌐 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:

Terminal window
go get github.com/balramadan/distlimit@v1.1.0

What’s Changed

New Contributors

Full Changelog: https://github.com/balramadan/distlimit/compare/v1.0.1...v1.1.0

v1.1.1

🐛 Bug Fixes

  1. 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).
  1. 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.
  1. 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

  1. 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.
  1. 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.
  1. 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:

Terminal window
go get -u github.com/balramadan/distlimit@v1.1.1

What’s Changed

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.Observer interface and metrics.Event snapshot 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: Limiter internal state refactored to atomic.Pointer[Policy]. Calling limiter.UpdatePolicy(limit, window) updates limits instantly with zero lock contention ($O(1)$ zero lock delay).
  • Multi-Tenant PolicyResolver: Added PolicyResolver interface allowing dynamic tier-based rate limit rules per key (e.g., VIP vs Free tiers) via WithPolicyResolver().

3. Middleware Route Labeling (WithRouteLabeling)

  • Context helper utilities ContextWithRoute(ctx, route) and RouteFromContext(ctx).
  • Added WithRouteLabeling(true) option across all middleware adapters (net/http, Gin, Echo v4, Echo v5, Fiber v3, and gRPC). This passes parametrized route patterns (e.g. /api/v1/users/:id or gRPC FullMethod) directly into metric labels.

📂 Working Examples


What’s Changed

Full Changelog: https://github.com/balramadan/distlimit/compare/v1.1.1...v1.2.0