Providers

Hybrid

Local fast-path admission with periodic Redis synchronization for very high throughput distributed workloads.

The hybrid provider combines local admission speed with Redis-backed shared 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.

Why choose Hybrid

  • local-speed admission decisions
  • much lower Redis load than pure Redis mode
  • distributed limiting without paying a Redis round-trip on every request

What to expect

  • methods are async
  • keys use RedisKey
  • local state is flushed to Redis every SyncInterval
  • decisions can temporarily lag behind the latest remote state

The main tuning knob

SyncInterval sets local-to-Redis flush cadence.

  • smaller values reduce lag and increase Redis pressure
  • larger values improve throughput and reduce Redis pressure

Construct it with HybridRateLimiterProvider::builder(connection) and configure a namespace prefix plus the sync interval. Background synchronization always runs; stale-state cleanup is a separate optional loop. See the Hybrid quickstart for a full setup.

Reading and priming counters

Both strategies expose reads, conditional updates, and lifecycle mutations. Hybrid variants coordinate local pending state with Redis:

  • get(key) reads Redis and overlays this instance's pending counts and declines.
  • get_estimate(key) may answer from initialized local state; undefined or expired cached state refreshes from Redis.
  • Conditional updates compare Redis history plus a protected snapshot of this instance's pending state. Comparator misses leave pending state untouched. Matches preserve increments racing after snapshot instead of dropping them.
  • Lifecycle revisions prevent stale cached baselines from undoing a rate change, deletion, or clear. Pending work held by another instance may recreate a deleted or cleared key afterward.
use trypema::RateLimitComparator;

// Raise the window total to at least `used`; idempotent, safe to retry.
provider
    .absolute()
    .set_if(&key, &rate, RateLimitComparator::Lt(used), used)
    .await?;

Best fit

Choose hybrid for high-throughput APIs where distributed visibility matters, but the pure Redis provider is too expensive on the hot path.

If you need every decision to read remote state directly, use Redis instead.