Distributed Rate Limiting for Rust.
High-performance, ergonomic primitives for local (in-memory), Redis-backed, and hybrid rate limiting. Built for Tokio with atomic Lua scripts and fractional rates.
cargo add trypema
use std::sync::Arc; use trypema::{RateLimit, RateLimitDecision, RateLimiter}; let rate = RateLimit::try_from(10.0).unwrap(); // 10 req/s // Absolute: allow or reject match rl.local().absolute().inc("user_123", &rate, 1) { RateLimitDecision::Allowed => { /* proceed */ } RateLimitDecision::Rejected { retry_after_ms, .. } => { eprintln!("retry in {retry_after_ms}ms"); } _ => {} } // Suppressed: smooth degradation match rl.local().suppressed().inc("user_123", &rate, 1) { RateLimitDecision::Allowed => { /* proceed */ } RateLimitDecision::Suppressed { is_allowed, .. } => { if is_allowed { /* proceed */ } else { /* shed load */ } } _ => {} }
Three providers, one API
Choose the backend that fits your deployment. The API is the same across all three.
Local
In-process DashMap + atomics. Sub-microsecond latency. No external dependencies. Ideal for single-server APIs and CLI tools.
Redis
Atomic Lua scripts against Redis 6.2+. One network round-trip per call. Distributed rate limits across processes and servers.
Hybrid
Local fast-path with periodic Redis sync. Sub-microsecond admission latency with distributed consistency. Best for high-throughput APIs.
Two strategies
Choose strict enforcement or probabilistic suppression depending on your traffic pattern.
Absolute
Deterministic sliding-window enforcement. Requests under capacity are Allowed, requests over it are Rejected with backoff hints (retry_after_ms). Simple and predictable.
Suppressed
Probabilistic degradation inspired by Ably. Near capacity, an increasing fraction of requests are denied rather than all at once. The suppression factor (0.0 to 1.0) tells you exactly how close a key is to its limit.
Built for production
Fractional rates
Support for f64 rate limits like 0.5 req/s (one request every 2 seconds) or 5.5 req/s. Sliding windows avoid fixed-window boundary resets.
Background cleanup
Automatic stale-key eviction via a background loop that holds only a Weak reference — no leak risk, no manual teardown.
Thread-safe
Designed for Arc<RateLimiter>. DashMap shard-level locking and atomic counters. Safe for concurrent use without external synchronisation.

