February 19, 2026   -   David Oyinbo

Trypema Rate Limiter

Trypema is a Rust rate limiting library for enforcing per-key request rates with either ultra-fast local state or Redis-backed shared state. It implements a sliding window algorithm (Absolute) and a graceful degradation mode (Suppressed), with practical details like fractional rates, retry hints, and a cleanup loop for high-cardinality keys.

RustRate LimitingRedisLibraryDistributed Systems
Trypema logo

Name Inspiration

The name “Trypema” is inspired by the Koine Greek word “trypematos” ("hole/opening"), from the phrase “through the eye of a needle” (Matthew 19:24; Mark 10:25; Luke 18:25). It’s a reminder that good rate limiting is about narrowing the gate under load: letting the right work through while keeping systems stable.

Overview

Trypema provides two providers (Local + Redis) and two strategies (Absolute + Suppressed) so you can enforce per-key request rates with low overhead and clear behavior near/over capacity. The Absolute strategy uses a sliding window algorithm to make enforcement predictable and fair across time boundaries. For distributed setups, Redis operations are implemented as atomic scripts so the admission check and increment happen together, making it suitable for multi-instance APIs and worker fleets. The distributed limiter approach is inspired by Ably's write-up: https://ably.com/blog/distributed-rate-limiting-scale-your-platform

Basic usage

Local (in-process)

[dependencies]
trypema = "1"
use trypema::{RateLimit, RateLimitDecision};

// `rl`: a shared `RateLimiter` created once at startup
let rate = RateLimit::try_from(5.0).unwrap();

// Example key: per-user or per-IP
let key = "user:123";

match rl.local().absolute().inc(key, &rate, 1) {
    RateLimitDecision::Allowed => {
        // proceed
    }
    RateLimitDecision::Rejected { retry_after_ms, .. } => {
        // reject (e.g. HTTP 429) and set a Retry-After hint
        let _ = retry_after_ms;
    }
    RateLimitDecision::Suppressed { .. } => unreachable!("absolute never suppresses"),
}

Redis (distributed)

[dependencies]
trypema = { version = "1", features = ["redis-tokio"] }
redis = { version = "0.27", features = ["aio", "tokio-comp"] }
tokio = { version = "1", features = ["rt", "time"] }
use trypema::{RateLimit, RateLimitDecision};
use trypema::redis::RedisKey;

let rate = RateLimit::try_from(10.0).unwrap();
// Note: RedisKey is restricted to a safe character set (e.g. ':' is rejected)
let key = RedisKey::try_from("ip_203.0.113.10".to_string()).unwrap();

// Atomic admission check + increment via Redis Lua script
match rl.redis().absolute().inc(&key, &rate, 1).await.unwrap() {
    RateLimitDecision::Allowed => {
        // proceed
    }
    RateLimitDecision::Rejected { retry_after_ms, .. } => {
        let _ = retry_after_ms;
    }
    RateLimitDecision::Suppressed { .. } => unreachable!("absolute never suppresses"),
}

Graceful degradation (Suppressed)

use trypema::{RateLimit, RateLimitDecision};

let rate = RateLimit::try_from(25.0).unwrap();
let key = "tenant:42:search";

match rl.local().suppressed().inc(key, &rate, 1) {
    RateLimitDecision::Allowed => {
        // normal path
    }
    RateLimitDecision::Suppressed { is_allowed: true, .. } => {
        // near capacity: allow, but consider cheaper/faster code paths
    }
    RateLimitDecision::Suppressed { is_allowed: false, .. } => {
        // shed load (e.g. serve cached response)
    }
    RateLimitDecision::Rejected { .. } => {
        // hard cutoff (over hard limit)
    }
}

Highlights

Providers

  • Local provider for ultra-low latency in-process limiting
  • Redis provider for shared limits across multiple instances

Strategies

  • Absolute: deterministic sliding-window enforcement
  • Suppressed: graceful degradation near capacity

Ergonomics

  • Fractional rates (f64)
  • Retry hints (e.g. retry_after_ms)
  • Cleanup loop for stale keys

Use cases

  • HTTP middleware (per user/IP/route)
  • Worker queues (per tenant/job type)
  • Downstream protection for internal clients

Documentation

  • Docs website with guides, concepts, strategies, and provider reference
  • Quickstarts for Local and Redis-backed setups

Other Projects

May 13, 2024

Canvas Infinity & Circle Mouse

Pet project exploring HTML Canvas and JavaScript animations—drawing an infinity curve and a circle following the mouse.

JavaScriptHTML CanvasAnimation
June 1, 2022

iPay (Nuxt 3 Pet Project)

A simple Nuxt 3 site built to explore the Nuxt 3 ecosystem, routing, layouts, and component patterns.

Nuxt 3VuePet Project
June 27, 2025

Actix Web Starter Template

Production-ready Rust/Actix Web REST API starter with RBAC auth, SeaORM/PostgreSQL, Kafka-based email, and Docker tooling.

RustActix WebSeaORM

Let's build something together

Available for senior engineering roles, consulting, and architecture reviews.

© 2026 David Oyinbo