What it is
Polly is a .NET resilience library providing retry, circuit breaker, timeout, bulkhead isolation, rate limiting and fallback as composable policies.
Build a resilience pipeline from strategies. Order matters: strategies added first are outermost, so a timeout added before retry bounds the whole operation.
Installation
dotnet add package PollyGetting started
The smallest useful thing you can do with it, and what each part means.
csharp
var pipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
.AddRetry(new RetryStrategyOptions<HttpResponseMessage>
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromMilliseconds(200),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true, // avoids synchronised retry storms
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.HandleResult(r => (int)r.StatusCode >= 500)
.Handle<HttpRequestException>(),
})
.AddCircuitBreaker(new CircuitBreakerStrategyOptions<HttpResponseMessage>
{
FailureRatio = 0.5,
SamplingDuration = TimeSpan.FromSeconds(30),
BreakDuration = TimeSpan.FromSeconds(15),
})
.AddTimeout(TimeSpan.FromSeconds(10))
.Build();
var response = await pipeline.ExecuteAsync(
async ct => await client.GetAsync(url, ct), cancellationToken);Advanced usage
Where the library earns its place over a simpler alternative.
csharp
builder.Services.AddHttpClient<BookApiClient>(c =>
{
c.BaseAddress = new Uri("https://api.example.com");
})
.AddStandardResilienceHandler(options =>
{
options.Retry.MaxRetryAttempts = 3;
options.CircuitBreaker.FailureRatio = 0.5;
options.AttemptTimeout.Timeout = TimeSpan.FromSeconds(5);
options.TotalRequestTimeout.Timeout = TimeSpan.FromSeconds(20);
});Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- BrokenCircuitException
- The breaker is open because the failure ratio was exceeded. This is intended — handle it with a fallback rather than retrying through it.
- Retries made an outage worse
- No jitter, no budget, or retrying non-idempotent writes. Add jitter and cap total attempts.
Best practices
- Only retry idempotent operations, or you will duplicate side effects.
- Always enable jitter — synchronised retries turn a partial outage into a full one.
- Pair retries with a circuit breaker so a failing dependency stops receiving traffic.
- Set both a per-attempt and a total timeout; one alone leaves a gap.
Background
Why it exists, and what it was reacting to.
Polly encodes the resilience patterns from Michael Nygard's Release It! as reusable strategies, and is now integrated into Microsoft's own HTTP client factory.
