Trypema Rate Limiter
Name and Biblical Inspiration
The name Trypema is derived from the Koine Greek word "τρυπήματος" (trypematos), meaning "hole" or "opening." It appears in the phrase "διὰ τρυπήματος ῥαφίδος" ("through the eye of a needle"), spoken by Jesus in three of the four Gospels:
- Matthew 19:24 — "Again I tell you, it is easier for a camel to go through the eye of a needle than for someone who is rich to enter the kingdom of God."
- Mark 10:25 — "It is easier for a camel to go through the eye of a needle than for someone who is rich to enter the kingdom of God."
- Luke 18:25 — "Indeed, it is easier for a camel to go through the eye of a needle than for someone who is rich to enter the kingdom of God."
Just as the eye of a needle is a narrow passage that restricts what can pass through, a rate limiter is a narrow gate that controls the flow of requests into a system.
Overview
Trypema is a sliding-window rate limiting crate with:
- Local in-memory limiting for single-process workloads
- Redis best-effort distributed limiting with atomic Lua scripts
- Hybrid best-effort distributed limiting with a local fast path and periodic Redis sync
Each provider offers:
- Absolute deterministic allow/reject decisions
- Suppressed probabilistic degradation near or above the target rate
Picking a Provider
| Provider | Best for | Trade-off |
|---|---|---|
| Local | single-process services, jobs, CLIs | not shared across processes |
| Redis | shared limits across processes or machines | every check performs Redis I/O |
| Hybrid | high-throughput distributed request paths | state can lag behind Redis by sync_interval_ms |
Redis and hybrid providers require Redis 7.2+ and exactly one runtime feature: redis-tokio or
redis-smol.
Installation
Local-only:
[]
= "1"
Redis with Tokio:
[]
= { = "1", = ["redis-tokio"] }
Redis with Smol:
[]
= { = "1", = ["redis-smol"] }
Quick Start
Common Types
RateLimit is the per-second limit value used by all providers. RedisKey is the validated key
type required by the Redis and hybrid providers. RateLimitDecision is the result returned by
inc() and is_allowed(), and RateLimiter is the top-level entry point used throughout the
examples.
use RateLimit;
use RedisKey;
let _rate_a = new.unwrap;
let _rate_b = try_from.unwrap;
let _rate_c = new_or_panic;
let _key_a = new.unwrap;
let _key_b = try_from.unwrap;
let _key_c = new_or_panic;
Create a RateLimiter
These examples show the local-only and Redis-enabled builder paths.
use ;
let rl = default
// Optional: override the sliding window size.
.window_size_seconds
// Optional: override bucket coalescing.
.rate_group_size_ms
// Optional: tune suppressed-mode headroom.
.hard_limit_factor
// Optional: tune cleanup cadence.
.cleanup_interval_ms
.build
.unwrap;
let rate = try_from.unwrap;
assert!;
use ;
let rl = builder.build.unwrap;
let rate = try_from.unwrap;
assert!;
use ;
use RedisKey;
async
use Arc;
use ;
use LocalRateLimiterOptions;
let options = RateLimiterOptions ;
let rl = new;
rl.run_cleanup_loop;
let rate = try_from.unwrap;
assert!;
build() starts the cleanup loop automatically. RateLimiter::new(...) does not, so call
run_cleanup_loop() yourself when you want background cleanup of stale keys.
Local Read-Only Check
use ;
let rl = builder.build.unwrap;
let limiter = rl.local.absolute;
let rate = try_from.unwrap;
assert!;
assert!;
Read Current Suppression State
use RateLimiter;
let rl = builder.build.unwrap;
let sf = rl.local.suppressed.get_suppression_factor;
assert_eq!;
Redis Absolute
use ;
use RedisKey;
async
Redis Suppressed State
use RateLimiter;
use RedisKey;
async
Hybrid Absolute
use ;
use RedisKey;
async
Rate Limit Decisions
Every strategy returns RateLimitDecision:
Allowedmeans the request should proceed.Rejectedmeans the absolute strategy denied the request and includes best-effort backoff hints.Suppressedmeans the suppressed strategy is active; checkis_allowedfor the admission result.
Notes
- Rate limits are sticky per key: the first
inc()stores the key's rate limit. - Bucket coalescing trades timing precision for lower overhead.
- Redis and hybrid modes provide best-effort distributed limiting, not strict linearizability.
Testing Redis-Backed Docs
The canonical runnable examples live in the crate docs and API docs. Redis and hybrid doctests
need a live Redis instance and REDIS_URL, for example:
REDIS_URL=redis://127.0.0.1:6379/
Use redis-smol instead when validating the Smol-backed feature set.