PollyRedis 1.0.0
See the version list below for details.
dotnet add package PollyRedis --version 1.0.0
NuGet\Install-Package PollyRedis -Version 1.0.0
<PackageReference Include="PollyRedis" Version="1.0.0" />
<PackageVersion Include="PollyRedis" Version="1.0.0" />
<PackageReference Include="PollyRedis" />
paket add PollyRedis --version 1.0.0
#r "nuget: PollyRedis, 1.0.0"
#:package PollyRedis@1.0.0
#addin nuget:?package=PollyRedis&version=1.0.0
#tool nuget:?package=PollyRedis&version=1.0.0
PollyRedis
Polly v8 resilience for StackExchange.Redis.
Automatic retry with exponential back-off on RedisConnectionException and RedisTimeoutException, circuit breaker to stop hammering a degraded cluster, and per-command timeout — wired up in one line via IServiceCollection or IConnectionMultiplexer.
Why PollyRedis?
Redis is often the first thing that fails under load, and StackExchange.Redis's built-in retry is limited. Production Redis clusters experience:
| Scenario | Without PollyRedis | With PollyRedis |
|---|---|---|
| Redis node restart | Requests fail immediately | Retries with exponential back-off |
| Transient network blip | Command throws RedisConnectionException |
Retried transparently |
| Redis timeout | RedisTimeoutException propagates |
Retried up to MaxRetries times |
| Sustained outage | Every command waits for timeout | Circuit opens; fails fast immediately |
| Slow Redis | Commands block indefinitely | Per-command timeout enforced |
Installation
dotnet add package PollyRedis
Quick Start
With dependency injection
// Program.cs
builder.Services.AddSingleton<IConnectionMultiplexer>(
ConnectionMultiplexer.Connect("localhost:6379"));
builder.Services.AddPollyRedis();
// Inject IResilientRedisDatabase wherever you need Redis
public class CacheService(IResilientRedisDatabase db)
{
public Task<RedisValue> GetAsync(string key) => db.StringGetAsync(key);
public Task SetAsync(string key, string value, TimeSpan ttl)
=> db.StringSetAsync(key, value, ttl);
}
Direct extension on IConnectionMultiplexer
var multiplexer = ConnectionMultiplexer.Connect("localhost:6379");
IResilientRedisDatabase db = multiplexer.GetResilientDatabase(options =>
{
options.MaxRetries = 4;
options.CommandTimeout = TimeSpan.FromSeconds(3);
});
var value = await db.StringGetAsync("my-key");
Configuration
builder.Services.AddPollyRedis(options =>
{
// Retry
options.MaxRetries = 3; // default: 3
options.BaseDelay = TimeSpan.FromMilliseconds(200); // default: 200 ms
options.MaxDelay = TimeSpan.FromSeconds(10); // default: 10 s
// Circuit breaker
options.CircuitBreakerMinimumThroughput = 5; // default: 5
options.CircuitBreakerFailureRatio = 0.5; // default: 0.5 (50%)
options.CircuitBreakerSamplingDuration = TimeSpan.FromSeconds(30);
options.CircuitBreakerBreakDuration = TimeSpan.FromSeconds(30);
// Timeout (per command)
options.CommandTimeout = TimeSpan.FromSeconds(5); // default: 5 s
// Add extra exception types to treat as transient
options.AdditionalTransientExceptions.Add(typeof(SocketException));
});
Supported Operations
IResilientRedisDatabase covers the most common Redis commands:
| Category | Methods |
|---|---|
| String | StringGetAsync, StringSetAsync, StringIncrementAsync, StringDecrementAsync |
| Key | KeyExistsAsync, KeyDeleteAsync, KeyExpireAsync |
| Hash | HashGetAsync, HashSetAsync, HashGetAllAsync, HashDeleteAsync |
| List | ListLeftPushAsync, ListRightPopAsync, ListLengthAsync |
| Set | SetAddAsync, SetRemoveAsync, SetContainsAsync |
| Sorted Set | SortedSetAddAsync, SortedSetScoreAsync |
| Escape hatch | ExecuteAsync<T>(Func<IDatabase, Task<T>>) for any command |
Custom command (escape hatch)
// Any IDatabase operation wrapped in the Polly pipeline
var result = await db.ExecuteAsync(d => d.StringGetRangeAsync("key", 0, -1));
Pipeline order
Command
└─► Retry (exponential back-off on connection/timeout errors)
└─► Circuit Breaker (opens on sustained failures)
└─► Timeout (per-command deadline)
└─► IDatabase → Redis
Comparison
| Raw SE.Redis | SE.Redis built-in retry | PollyRedis | |
|---|---|---|---|
Retry on RedisConnectionException |
❌ | ⚠️ limited | ✅ |
Retry on RedisTimeoutException |
❌ | ⚠️ limited | ✅ |
| Exponential back-off with jitter | ❌ | ❌ | ✅ |
| Circuit breaker | ❌ | ❌ | ✅ |
| Per-command timeout | ❌ | ❌ | ✅ |
| DI integration | ❌ | ❌ | ✅ |
| Custom transient exceptions | ❌ | ❌ | ✅ |
| Polly v8 pipeline | ❌ | ❌ | ✅ |
Related Packages
| Package | Downloads | Description |
|---|---|---|
| PollyChaos | Chaos engineering / fault injection for Polly v8 | |
| PollyMediatR | Polly v8 pipelines for MediatR request handlers | |
| PollyEFCore | Polly v8 resilience for EF Core queries and SaveChanges | |
| PollyHealthChecks | ASP.NET Core health checks for Polly v8 circuit breakers | |
| PollyOpenAI | Polly v8 resilience for OpenAI and Azure OpenAI API calls | |
| PollyBackoff | Custom back-off strategies for Polly v8 |
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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. |
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
- StackExchange.Redis (>= 2.13.17)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
- StackExchange.Redis (>= 2.13.17)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Initial release. Retry on RedisConnectionException/RedisTimeoutException with exponential back-off, circuit breaker, timeout, and DI extensions.