HTTP resilience in .NET 10 without Polly: three options
Polly's Open Source Maintenance Fee, starting 16 November 2026, will not affect most teams, but the article maps three ways to keep Polly out of your dependency graph entirely. Mukesh Murugan runs Microsoft.Extensions.Http.Resilience, Kevlar and a hand-written DelegatingHandler stack against the same flaky API and compares the results.
Key points
- The fee only hits direct references to the next major Polly version released after 16 November 2026; existing 8.x versions stay free
- Polly arriving through Microsoft.Extensions.Http.Resilience is exempt; check your projects with `dotnet list package --include-transitive`
- `AddStandardResilienceHandler()` retries POSTs by default, so add `DisableForUnsafeHttpMethods()` for non-idempotent endpoints
- Kevlar's `AddStandardShield()` gives a Polly-free pipeline: 30s total timeout, 10s attempt timeout, three jittered retries
- Keep hand-rolled circuit breaker state outside the handler, because IHttpClientFactory rebuilds the chain every two minutes
- Register a separate named client per downstream dependency so earlier failures cannot open another circuit early
Polly moved to the Open Source Maintenance Fee in July 2026; the code stays BSD-3-Clause and nothing breaks on 16 November. Only direct references to the next major version released after that date fall under the fee: US $20 per month per organization, for companies earning at least $20,000 from a product that uses it. Transitive use through Microsoft.Extensions.Http.Resilience is exempt, and `dotnet list package --include-transitive` shows whether Polly sits in Top-level or Transitive packages.
The first alternative is Microsoft's `AddStandardResilienceHandler()`, and the author insists on `DisableForUnsafeHttpMethods()` because the default retried a failed POST and created the order twice. Kevlar offers a comparable pipeline via `AddStandardShield()` but ships different defaults and has a single maintainer. The hand-rolled route needs three DelegatingHandler classes plus a circuit breaker state object kept outside the handler, since `IHttpClientFactory` rebuilds the handler chain every two minutes.
Real-world use
- An e-commerce backend that POSTs to non-idempotent order or payment endpoints
- A microservice that must drop Polly from its dependency graph ahead of a corporate license review
- An integration layer calling several third-party services (shipping, payments, SMS), each needing its own timeout and circuit settings
- A background worker that must stop hammering a dead downstream service instead of blocking every request
Why it matters
For most teams the right move is not paying the fee but dropping the direct reference and switching to Microsoft's package — and the default retry behavior can silently duplicate writes on non-idempotent endpoints.