rok-rate-limit
Rate limiting middleware for Axum with in-memory and Redis backends, 429 responses, and standard headers.
Part of the Rok Framework — a full-stack Rust web framework built on Axum 0.8 and SQLx 0.8.
Features
- Sliding window algorithm — smooth rate limit without burst spikes at window boundaries
- In-memory backend using DashMap — zero-dependency, suitable for single-process deployments
- Redis backend — distributed rate limiting across multiple server processes
- Pluggable key extraction — per-IP, per-authenticated-user, per-API-key, or custom closure
- Standard rate limit response headers (
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset) Retry-Afterheader on 429 responses so clients know when to retry- Per-route granularity — apply different limits to login vs. API endpoints
- RFC 6585 compliant
429 Too Many Requestsresponses with JSON body
Installation
[]
= "0.2"
Redis backend:
= { = "0.2", = ["redis"] }
Quick Start
use Duration;
use ;
use ;
// 100 requests per 60 seconds, keyed by client IP
let global_limiter = new
.key;
// Tighter limit on the login endpoint to slow brute-force attempts
let login_limiter = new
.key;
let app = new
.route
.layer
.route
.layer;
Core API
RateLimitLayer
KeyExtractor
// Rate-limit by remote IP address (X-Forwarded-For aware)
ip
// Rate-limit by the value of a specific header
header
// Rate-limit by the authenticated user's JWT `sub` claim
jwt_sub
// Rate-limit by any custom function over the request
custom
Response Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1716912060 (Unix timestamp when the window resets)
Retry-After: 18 (seconds; only present on 429 responses)
Feature Flags
| Flag | Description | Default |
|---|---|---|
redis |
Redis backend via fred async client |
disabled |
memory |
DashMap in-memory backend | enabled |
Integration
rok-rate-limit pairs naturally with rok-auth to protect authentication endpoints.
Mount a strict limiter on auth routes and a more generous one on API routes:
use AuthLayer;
use ;
// Authenticated routes: rate-limit per user, not per IP
let api_limiter = new
.key;
let app = new
.nest
.layer;
For distributed deployments, switch to the Redis backend via RateLimitLayer::redis(...).
The Redis backend uses Lua scripts for atomic sliding-window increments, so limits are
accurate across any number of server instances.
License
MIT