Rate limiting
Rate limiting
Sliding-window rate limiting via the trypema crate, re-exported under distkit::trypema.
distkit's rate limiting is the trypema crate, re-exported in full under distkit::trypema. Enable the trypema feature to pull it in:
[dependencies]
distkit = { version = "0.5", features = ["trypema"] }
If you're only doing rate limiting, you can also depend on trypema directly - the distkit re-export is for projects that want it alongside the other primitives.
Full provider, strategy, and tuning documentation lives on the trypema docs site. This page is a quick on-ramp.
What it offers
- Sliding-window limiting with configurable window size and rate (rates are
f64, so0.5 req/sis valid). - Three providers -
local(in-process),redis(distributed, one round-trip per call), andhybrid(local fast-path with periodic Redis sync). - Two strategies -
absolute(deterministic allow/reject) andsuppressed(probabilistic shedding as you approach capacity).
Local rate limiting
use std::sync::Arc;
use distkit::trypema::{
HardLimitFactor, RateGroupSizeMs, RateLimit, RateLimitDecision,
RateLimiter, RateLimiterOptions, SuppressionFactorCacheMs, WindowSizeSeconds,
local::LocalRateLimiterOptions,
};
let rl = Arc::new(RateLimiter::new(RateLimiterOptions {
local: LocalRateLimiterOptions {
window_size_seconds: WindowSizeSeconds::try_from(60).unwrap(),
rate_group_size_ms: RateGroupSizeMs::try_from(100).unwrap(),
hard_limit_factor: HardLimitFactor::default(),
suppression_factor_cache_ms: SuppressionFactorCacheMs::default(),
},
}));
rl.run_cleanup_loop();
let rate = RateLimit::try_from(10.0).unwrap(); // 10 requests per second
match rl.local().absolute().inc("user_123", &rate, 1) {
RateLimitDecision::Allowed => { /* process the request */ }
RateLimitDecision::Rejected { retry_after_ms, .. } => {
eprintln!("rate limited, retry in {retry_after_ms} ms");
}
_ => {}
}
Distributed rate limiting
For enforcement shared across processes, add the Redis provider options and call redis() (one round-trip per call) or hybrid() (local fast-path, periodic sync):
use distkit::trypema::{
redis::{RedisKey, RedisRateLimiterOptions},
hybrid::SyncIntervalMs,
};
// ... build RateLimiterOptions with both `local` and `redis` set ...
let key = RedisKey::try_from("user_123".to_string())?;
let rate = RateLimit::try_from(50.0)?;
let decision = rl.redis().absolute().inc(&key, &rate, 1).await?;
// or, for the highest-throughput distributed option:
let decision = rl.hybrid().absolute().inc(&key, &rate, 1).await?;
Redis-backed providers require Redis 7.2+. For the complete configuration surface - suppression tuning, hybrid sync intervals, and the strategy internals - see the trypema documentation.

