Sliding-window rate limiting, from one process to a fleet.

Trypema gives Rust services independently built local, Redis, and hybrid providers. Use binary admission or gradual probabilistic shedding without changing the underlying rate model.

Cargo.toml
[dependencies]
trypema = "2"
main.rs
use trypema::{RateLimit, RateLimitDecision, RateLimiterBuilder};
use trypema::local::LocalRateLimiterProvider;

fn main() {
    let provider = LocalRateLimiterProvider::builder().build().unwrap();
    let rate = RateLimit::per_second_or_panic(10.0);

    match provider.absolute().inc("user_123", &rate, 1) {
        RateLimitDecision::Allowed => println!("allowed"),
        RateLimitDecision::Rejected { retry_after, .. } => {
            println!("retry in {retry_after:?}");
        }
        RateLimitDecision::Suppressed { .. } => unreachable!(),
    }
}

Choose where state lives

All providers expose absolute and suppressed limiters. The difference is latency, coordination, and how current each instance's view can be.

    Local

    Synchronous, in-process state and the lowest overhead. Limits apply independently to each process.

    Redis

    Async shared state with Redis I/O on every call. Best when instances need the freshest remote view.

    Hybrid

    Local admission with periodic Redis synchronization. Higher throughput, with bounded visibility lag.

Three paper-craft rate-limiter topologies showing local state, direct shared Redis state, and local state synchronized to Redis.
Local keeps state in one process; Redis centralizes every call; hybrid periodically synchronizes local state to Redis.

Choose how pressure is handled

    Absolute

    Each call is allowed or rejected. Rejections include best-effort timing and released-capacity hints.

    Suppressed

    Denial probability rises with pressure, allowing gradual shedding instead of an abrupt cutoff.

One explicit rate model

A RateLimit is normalized per second. Multiplying it by WindowSize gives the live-window capacity; BucketSize controls how nearby increments are grouped.

    Live sliding windows

    Reads include only live buckets. Unknown keys return zero without creating state; expired history may be lazily evicted.

    Sticky capacity

    The first increment stores a key's computed capacity. Later increments keep it until a matched conditional update replaces it.

    Safe reconciliation

    Comparator-gated writes can replace history or preserve its newest or oldest side. A matched zero removes the key.

    Validated configuration

    Semantic types make units and constraints explicit for windows, buckets, suppression, and hybrid synchronization.

Know the production boundaries

    Best-effort concurrency

    Admission is not a strict cross-caller transaction. Concurrent callers can temporarily overshoot a limit.

    Redis requirements

    Redis and hybrid require Redis 7.2+ and exactly one crate feature: redis-tokio or redis-smol.

    Automatic cleanup

    Builders start stale-state cleanup by default. It can be disabled or controlled with idempotent start and stop methods.

Go deeper

    Getting Started

    Install v2 and run local, Redis, or hybrid quickstarts.

    Concepts

    Understand keys, rates, windows, configuration, and decisions.

    API Map

    Find providers, shared types, and core operations without reading generated API pages first.

    Benchmarks

    Compare providers using documented workloads, throughput, and tail latency.