Getting Started
Quickstart (Local)
[object Object]
Use the local provider when all rate limiting happens inside one process and you want the lowest possible overhead.
Create a limiter with defaults
RateLimiter::builder().build() is the shortest path. It also starts background cleanup automatically.
use trypema::{RateLimit, RateLimitDecision, RateLimiter};
let rl = RateLimiter::builder().build().unwrap();
let rate = RateLimit::try_from(5.0).unwrap();
assert!(matches!(
rl.local().absolute().inc("user_123", &rate, 1),
RateLimitDecision::Allowed
));
Create a limiter with explicit options
Use RateLimiter::new(...) when you want full control. In this path, you start cleanup yourself.
use std::sync::Arc;
use trypema::{
HardLimitFactor, RateGroupSizeMs, RateLimit, RateLimiter, RateLimiterOptions,
SuppressionFactorCacheMs, WindowSizeSeconds,
};
use trypema::local::LocalRateLimiterOptions;
let rl = Arc::new(RateLimiter::new(RateLimiterOptions {
local: LocalRateLimiterOptions {
window_size_seconds: WindowSizeSeconds::new_or_panic(60),
rate_group_size_ms: RateGroupSizeMs::new_or_panic(10),
hard_limit_factor: HardLimitFactor::new_or_panic(1.5),
suppression_factor_cache_ms: SuppressionFactorCacheMs::default(),
},
}));
rl.run_cleanup_loop();
let _rate = RateLimit::try_from(5.0).unwrap();
Read before you write
For the local absolute strategy, is_allowed(...) is the clearest way to inspect the current state without recording a request.
use trypema::{RateLimit, RateLimitDecision, RateLimiter};
let rl = RateLimiter::builder().build().unwrap();
let rate = RateLimit::try_from(5.0).unwrap();
assert!(matches!(
rl.local().absolute().is_allowed("user_123"),
RateLimitDecision::Allowed
));
assert!(matches!(
rl.local().absolute().inc("user_123", &rate, 1),
RateLimitDecision::Allowed
));
Inspect suppression state
get_suppression_factor(...) tells you how much shedding pressure is currently active for a key.
use trypema::{RateLimiter, RateLimit};
let rl = RateLimiter::builder().build().unwrap();
let rate = RateLimit::try_from(5.0).unwrap();
let limiter = rl.local().suppressed();
let _ = limiter.inc("user_123", &rate, 1);
assert_eq!(limiter.get_suppression_factor("fresh_key"), 0.0);
What this quickstart proves
- Local limiting needs no external services.
build()starts cleanup automatically, whilenew(...)does not.- Absolute gives read-style (
is_allowed) and write-style (inc) checks. - Suppressed mode exposes current pressure through
get_suppression_factor(...).

