RateLimitEngine: engineering rate limiting for .NET systems
A .NET 8 library for rate limiting that separates algorithms, state storage, and HTTP integration, with explicit behavior for concurrency, time boundaries, and Redis failure.
Context
Rate limiting looks like a simple counter until a real system has concurrent requests, multiple application instances, distributed state, weighted requests, and infrastructure failures. RateLimitEngine was designed to turn those concerns into a reusable, testable library.
Problem
The goal was to provide a stable rate-limiting abstraction that can use different algorithms without coupling the application to storage or HTTP integration details. The resulting decision also exposes meaningful signals such as Remaining, ResetAfter, and RetryAfter with explicit semantics.
Constraints & requirements
- Correct behavior under concurrent requests
- Local or shared state through Redis
- Separate algorithm, storage, and HTTP integration concerns
- Explicit behavior when Redis is unavailable
- Testable time-dependent behavior and window boundaries
- Weighted requests with costs greater than one permit
Approach
The design centers on IRateLimiter and an algorithm factory. Fixed Window, Sliding Window, Token Bucket, and GCRA remain separate from the application layer, while state can be stored in memory or Redis. ASP.NET Core integration is layered on top of the same core contract.
Application -> IRateLimiter -> Algorithm
-> State Store (Memory / Redis)
-> HTTP Integration (ASP.NET Core)Key decisions & trade-offs
| Decision | Reason |
|---|---|
| Separate algorithm and state | Algorithms or storage can change without changing the main rate-limiting contract. |
| Redis as shared state | Multiple application instances can enforce a common limit. |
| Redis server time | Distributed behavior is less dependent on clock differences between processes. |
| Explicit failure semantics | Backend failure behavior is part of the contract rather than a hidden implementation detail. |
| Weighted requests | Permit consumption can reflect the logical cost of different requests. |
Outcome
The result is a reusable .NET 8 library with four rate-limiting algorithms, in-memory and Redis backends, ASP.NET Core integration, weighted requests, and explicit failure and retry semantics in a separated architecture. The project has a 1.0.0 release. It demonstrates how a seemingly small feature can require abstraction design, concurrency handling, distributed behavior, and explicit reliability contracts.
Technical depth
- IRateLimiter and RateLimitDecision contracts
- Fixed Window, Sliding Window, Token Bucket, and GCRA
- Redis state with Lua scripts and server time for atomic transitions
- Separated Core, Algorithms, Redis, and ASP.NET Core integration
- Deterministic, testable behavior for time-dependent logic
Evidence
The code, design, and documentation are publicly inspectable on GitHub.
GitHub — RateLimitEngine
The repository contains the library, design documentation, examples, and project tests.
Open sourceRelated solutions
Related mathematics lesson
Working on a similar technical problem?
For problems involving reliability, concurrency, distributed state, or a critical technical module, we can discuss scope and an appropriate path forward.