Getting Started

Quickstart (Redis)

Share rate limits through Redis with one async Redis operation per call.

Use Redis provider when multiple instances must operate on shared limiter state.

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.

Add dependencies

[dependencies]
trypema = { version = "2", features = ["redis-tokio"] }
redis = { version = "1", features = ["aio", "tokio-comp", "connection-manager"] }
tokio = { version = "1", features = ["full"] }

Redis-backed providers require Redis 7.2+ and exactly one runtime feature: redis-tokio or redis-smol.

Build provider

use trypema::{BucketSize, RateLimit, RateLimitDecision, RateLimiterBuilder, WindowSize};
use trypema::redis::{RedisKey, RedisRateLimiterProvider};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let connection = redis::Client::open("redis://127.0.0.1:6379/")?
        .get_connection_manager()
        .await?;
    let provider = RedisRateLimiterProvider::builder(connection)
        .prefix(RedisKey::try_from("my-service")?)
        .window_size(WindowSize::minutes_or_panic(1))
        .bucket_size(BucketSize::milliseconds_or_panic(10))
        .build()?;

    let key = RedisKey::try_from("user_123")?;
    let rate = RateLimit::per_second_or_panic(5.0);
    assert!(matches!(
        provider.absolute().inc(&key, &rate, 1).await?,
        RateLimitDecision::Allowed
    ));

    Ok(())
}

Methods are async and accept &RedisKey. Absolute reads return u64; suppressed reads return SuppressedRateLimitSnapshot. Each Redis operation is atomic, while overall admission remains best-effort under concurrency.

The prefix is the shared Redis namespace; the operation key identifies one limited subject. All instances sharing limits should use the same prefix and limiter settings.

Next steps