AppRateLimiter.Redis 1.0.1

dotnet add package AppRateLimiter.Redis --version 1.0.1
                    
NuGet\Install-Package AppRateLimiter.Redis -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AppRateLimiter.Redis" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AppRateLimiter.Redis" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="AppRateLimiter.Redis" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AppRateLimiter.Redis --version 1.0.1
                    
#r "nuget: AppRateLimiter.Redis, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AppRateLimiter.Redis@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AppRateLimiter.Redis&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=AppRateLimiter.Redis&version=1.0.1
                    
Install as a Cake Tool

AppRateLimiter.Redis

Redis-backed distributed store for AppRateLimiter.

Use this when you run more than one instance of your app (for example several Kubernetes or EKS pods). The default in-memory store counts requests per process, so with N replicas the effective limit becomes limit x N, and a client load balanced across pods can slip past any single pod's counter. This package keeps one shared counter in Redis so the limit holds globally, no matter which instance serves each request.

Install

dotnet add package AppRateLimiter.Redis

This package depends on AppRateLimiter, so the core middleware comes with it.

Usage

Register the Redis store instead of AddAppRateLimiter(). Everything else (the middleware, the IP and claim rules) works exactly as documented in the core package.

// Connect with a configuration string:
builder.Services.AddRedisRateLimiter("my-redis:6379");

// Optionally namespace the keys (defaults to "rl:"):
builder.Services.AddRedisRateLimiter("my-redis:6379", keyPrefix: "rl:prod:");

If you already manage your own connection, pass an existing IConnectionMultiplexer and the store will reuse it:

var mux = ConnectionMultiplexer.Connect("my-redis:6379");
builder.Services.AddRedisRateLimiter(mux, keyPrefix: "rl:prod:");

Then place the middleware in the pipeline the same way as with the in-memory store:

var app = builder.Build();

// IP limiting before authentication.
app.UseRateLimiting(RateLimitRules.ByIp(permitLimit: 100, window: TimeSpan.FromMinutes(1)));

app.UseAuthentication();
app.UseAuthorization();

// Claim limiting after authentication.
app.UseRateLimiting(RateLimitRules.ByClaim("sub", permitLimit: 1000, window: TimeSpan.FromMinutes(1)));

app.Run();

How it stays correct and fast

  • Race free across pods. The whole sliding window read modify write runs inside a single Lua script, which Redis executes atomically. Concurrent requests from any number of instances cannot race, so there is no over admission.
  • One round trip per check. The script is cached server side and called via EVALSHA, so each decision is a single pipelined round trip on the shared multiplexer, typically sub millisecond inside the same VPC or AZ. The store is fully async and never blocks thread pool threads.
  • No pod clock skew. Time comes from the Redis server clock (via TIME), not from each pod's clock.
  • Bounded memory. Each bucket is given a TTL of twice the window (the sliding window counter only needs the current and previous window), so idle keys expire on their own with no manual cleanup.

Securing Redis in production

The rate limit keys hold client IPs and claim values (such as sub), so treat the Redis instance as sensitive infrastructure:

  • Keep it private. Never expose Redis to the public internet. Put it in a private subnet and allow inbound 6379 only from the app's security group. On EKS, prefer a managed endpoint (such as ElastiCache or MemoryDB) reachable only from the cluster. Leave protected-mode on.

  • Require authentication with least privilege. Use a Redis ACL user limited to the commands this store needs: EVAL, EVALSHA, SCRIPT, HMGET, HSET, PEXPIRE, TIME, PING.

    ACL SETUSER ratelimiter on >REPLACE_WITH_STRONG_SECRET ~rl:* +eval +evalsha +script +hmget +hset +pexpire +time +ping
    
  • Encrypt in transit. Enable ssl=true with a real hostname, and turn on in transit and at rest encryption on managed Redis.

  • Never hardcode the connection string. Load it from a secret (a Kubernetes Secret or AWS Secrets Manager), not from source:

    builder.Services.AddRedisRateLimiter(
        builder.Configuration.GetConnectionString("Redis")!,
        keyPrefix: "rl:prod:");
    

    A secured connection string looks like: my-redis.internal:6380,ssl=true,user=ratelimiter,password=<secret>,abortConnect=false

  • Namespace the keyspace. Use a distinct keyPrefix per app and environment so multiple services can safely share one cluster while their ACL scope (~rl:*) stays contained.

Fails closed

If Redis is unreachable the request errors rather than silently skipping the limit, so an outage cannot be used to bypass rate limiting.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on AppRateLimiter.Redis:

Package Downloads
AppRateLimiter.Web

Classic ASP.NET (System.Web) integration for AppRateLimiter: an async IHttpModule that applies the same IP and claim rate-limit rules to WebForms / MVC 5 / Web API 2 apps on .NET Framework. Reuses the core store (in-memory or distributed Redis).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 55 6/2/2026
1.0.0 45 6/2/2026