Documentation Index
Fetch the complete documentation index at: https://mintlify.com/nimanikoo/Dotnet-RateLimiter/llms.txt
Use this file to discover all available pages before exploring further.
[RedisRateLimit] lets you annotate any controller action with a per-endpoint, per-identity rate limit that is enforced across all application instances via Redis. Unlike the built-in [EnableRateLimiting] attribute — which relies on in-process, in-memory counters — [RedisRateLimit] stores its counters in Redis, making limits consistent in multi-instance and container deployments. The attribute itself is pure metadata; enforcement is handled by RedisRateLimitingMiddleware, which reads the metadata on every incoming request.
The RedisRateLimitAttribute Class
The attribute is defined in Attributes/RedisRateLimitAttribute.cs:
Parameters
Maximum number of requests allowed within the time window defined by
windowSeconds. Once this count is exceeded for a given identity + endpoint combination, the middleware returns 429 Too Many Requests until the window resets. For example, maxRequests: 2 allows exactly 2 requests per window.Duration of the rate limit window in seconds. The Redis key holding the request counter is set to expire after this many seconds. For example,
windowSeconds: 10 creates a 10-second sliding counter. This value is also written directly into the Retry-After response header so clients know when to retry.Basic Usage
Apply the attribute directly to any controller action. The example below limits callers to 2 requests per 10 seconds on theGET /test/limited endpoint:
RedisRateLimitingMiddleware — no Redis calls are made for them.
Multiple Endpoints with Different Limits
Each action can carry its own independent limit. The counters are keyed by{userType}:{identityKey}:{path}, so limits never bleed across endpoints:
The 429 Too Many Requests Response
When the rate limit is exceeded,RedisRateLimitingMiddleware short-circuits the pipeline and returns the following response — no controller code runs:
| Property | Value |
|---|---|
| HTTP status code | 429 Too Many Requests |
Retry-After header | Set to windowSeconds (e.g., "10" for a 10-second window) |
| Response body (authenticated user) | Dear user, you've reached your limit. Take a breath! |
| Response body (anonymous / guest) | Guest limit reached. Please sign up for more quota! |
- Authenticated — uses
ClaimTypes.NameIdentifierfromcontext.User, falling back tocontext.User.Identity.Nameor"authenticated_unknown". The Redis key prefix isuser:. - Anonymous — uses
context.Connection.RemoteIpAddress(falls back to"unknown"). The Redis key prefix isguest:.
rate_limit:{userType}:{identityKey}:{path}, for example:
How the Middleware Reads the Attribute
RedisRateLimitingMiddleware is not an ASP.NET Core filter. It runs as standard middleware and inspects endpoint metadata directly:
RedisRateLimitAttribute in its metadata, the middleware calls _next(context) immediately and exits without touching Redis.
Because the middleware relies on
context.GetEndpoint() to resolve the attribute, MapControllers() must be called during application setup — UseMiddleware<RedisRateLimitingMiddleware>() depends on the endpoint routing system having already matched the request to a controller action.[RedisRateLimit] vs [EnableRateLimiting]
Both attributes are present in this project — choose the right one for your scenario:
| Feature | [RedisRateLimit] | [EnableRateLimiting("PolicyName")] |
|---|---|---|
| Storage | Redis (distributed) | In-process memory |
| Multi-instance safe | ✅ Yes | ❌ No — each instance has its own counter |
| Identity-aware | ✅ Per-user or per-IP, per-endpoint | ❌ Global per policy |
| Configuration | Inline on the attribute (maxRequests, windowSeconds) | Defined once in AddCustomRateLimiter (window, permit limit, queue limit) |
| Enforcement | RedisRateLimitingMiddleware (custom) | UseRateLimiter() (built-in ASP.NET Core) |
| Available policies | Fixed window via atomic Lua | FixedWindowPolicy, SlidingWindowPolicy, ConcurrencyPolicy, BucketPolicy |
| Example | [RedisRateLimit(maxRequests: 2, windowSeconds: 10)] | [EnableRateLimiting("FixedWindowPolicy")] |
[RedisRateLimit] when you need per-identity enforcement that survives pod restarts or scales horizontally. Use [EnableRateLimiting] for lightweight, single-instance throttling or concurrency control.