touch_ratelimit

Crates.iotouch_ratelimit
lib.rstouch_ratelimit
version0.1.0
created_at2025-12-23 17:37:02.516723+00
updated_at2025-12-23 17:37:02.516723+00
descriptionA composable, extensible rate limiting crate for Rust
homepage
repositoryhttps://github.com/SPARSH1608/Touch_ratelimit
max_upload_size
id2001977
size41,290
Sparsh (SPARSH1608)

documentation

https://docs.rs/touch-ratelimit

README

touch-ratelimit

A composable, extensible rate limiting crate for Rust.

touch-ratelimit provides clean building blocks for implementing rate limiting in Rust applications using a clear separation of concerns:

  • Algorithms – how rate limiting works (e.g. token bucket)
  • Stores – where rate limiting state lives
  • Middleware – how rate limiting is applied to requests
  • Adapters – framework integrations (e.g. Axum)

The crate is designed to be framework-agnostic, storage-agnostic, and algorithm-agnostic, making it easy to extend without rewriting core logic.


Features

  • Token bucket rate limiting algorithm
  • In-memory storage backend
  • Tower-based middleware
  • Axum integration
  • Designed for extension (Redis, additional algorithms planned)

Installation

Core crate

[dependencies]
touch-ratelimit = "0.1"

With Axum integration

[dependencies]
touch-ratelimit = { version = "0.1", features = ["axum"] }
axum = "0.8"
tokio = { version = "1", features = ["full"] }

Example: Axum

use axum::{routing::get, Router};
use touch_ratelimit::{
    adapters::axum::axum_rate_limit_layer,
    storage::InMemoryStore,
    bucket::token_bucket::TokenBucket,
};

#[tokio::main]
async fn main() {
    let store = InMemoryStore::token_bucket(10.0, 1.0);

    let app = Router::new()
        .route("/", get(|| async { "hello" }))
        .layer(axum_rate_limit_layer(store));

    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

Requests exceeding the configured rate limit receive:

HTTP 429 Too Many Requests

Core Concepts

RateLimiter

A RateLimiter represents the rate-limiting logic for a single identity (e.g. one user, one IP address, one API key).

Examples include:

  • Token bucket
  • Sliding window (planned)
  • Leaky bucket (planned)

Each RateLimiter instance is stateful and is not shared across identities.


RateLimitStore

A RateLimitStore manages many RateLimiter instances and maps them to request keys.

Responsibilities include:

  • Creating rate limiters for new keys
  • Handling concurrency
  • Owning rate-limiting state

The store is responsible for where and how state is stored.


Middleware

Middleware enforces rate limits before forwarding requests to the inner service.

The core middleware is built on Tower and is framework-agnostic. Framework adapters (e.g. Axum) are thin wrappers around this middleware.


Storage Behavior (Important)

The default InMemoryStore keeps all rate-limiting state inside the application’s memory.

This means:

  • State is lost on restart
  • State is not shared across processes
  • Each server instance enforces limits independently

This is suitable for:

  • Development
  • Single-instance deployments
  • Edge or sidecar setups

Distributed stores (e.g. Redis) can be added without changing middleware or algorithms.


Key Extraction

The Axum adapter identifies requests using the x-forwarded-for header by default.

If the header is missing or invalid, rate limiting is skipped for that request.

This behavior is useful when running behind a reverse proxy or load balancer.


Extensibility

The crate is designed so new components can be added independently:

  • New algorithms can implement RateLimiter
  • New storage backends can implement RateLimitStore
  • New framework adapters can be built on top of the core middleware

No changes to existing middleware are required.


Commit count: 0

cargo fmt