actix-extensible-rate-limit
A flexible, backend-pluggable rate-limiting middleware for the actix-web framework.
Repository Health
Technical Analysis
actix-extensible-rate-limit is a rate-limiting middleware for actix-web built around extensibility. Rather than hard-coding a single strategy, it lets you derive the rate-limit key from arbitrary request context, compute dynamic limits and intervals per request, plug in custom storage backends and algorithms, and shape the response — from the 429 body to headers like x-ratelimit-remaining.
Out of the box it ships two backends: an in-memory fixed-window store backed by DashMap, and a Redis-backed store for distributed deployments. It also supports rolling back counts based on the eventual response status, so requests that fail for unrelated reasons don’t consume a client’s quota.
What You Get
- A RateLimiter middleware that plugs into any actix-web App via wrap
- An in-memory DashMap backend and a Redis backend for distributed limits
- Custom key derivation from request context (IP, headers, auth, etc.)
- Dynamic per-request limits and intervals rather than a single fixed rule
- Configurable 429 responses and automatic x-ratelimit-* headers
- Count rollback based on the eventual response status code
Common Use Cases
- Throttling API requests per client IP or API key
- Enforcing distributed rate limits across multiple app instances via Redis
- Applying different limits to different routes or authenticated tiers
Under The Hood
Architecture - The design cleanly separates concerns across three seams: an input function (built via SimpleInputFunctionBuilder in src/backend/input_builder.rs) maps a request to a key/limit/interval; a Backend trait (src/backend/mod.rs, implemented by memory.rs and redis.rs) stores counts and decides allow/deny; and the actix Transform/Service middleware (src/middleware/) ties them together, applying headers and rollback. This trait-based layering is what makes both the store and the algorithm swappable.
Tech Stack - Rust (edition 2021) on actix-web 4, using futures for the async service plumbing, thiserror for typed errors, and log for diagnostics. The in-memory backend uses dashmap (default feature) and the distributed backend uses redis with tokio async support, both gated behind Cargo features so you only compile what you use.
Code Quality - Tests live alongside the code (src/middleware/tests.rs) and use tokio’s test-util time control to exercise window expiry deterministically. Errors are modeled explicitly with thiserror, the module boundaries are tight, and a CHANGES.md tracks a considered release history.
API Design - The builder-driven API keeps the common case short — construct a backend, build a simple input function with an interval and count, wrap the middleware — while the underlying traits expose full control for advanced scenarios. Header injection and custom denial responses are opt-in via builder methods, so simple setups stay concise and complex ones remain expressible.