Kevlar.Extensions.Grpc
0.3.0
dotnet add package Kevlar.Extensions.Grpc --version 0.3.0
NuGet\Install-Package Kevlar.Extensions.Grpc -Version 0.3.0
<PackageReference Include="Kevlar.Extensions.Grpc" Version="0.3.0" />
<PackageVersion Include="Kevlar.Extensions.Grpc" Version="0.3.0" />
<PackageReference Include="Kevlar.Extensions.Grpc" />
paket add Kevlar.Extensions.Grpc --version 0.3.0
#r "nuget: Kevlar.Extensions.Grpc, 0.3.0"
#:package Kevlar.Extensions.Grpc@0.3.0
#addin nuget:?package=Kevlar.Extensions.Grpc&version=0.3.0
#tool nuget:?package=Kevlar.Extensions.Grpc&version=0.3.0
Kevlar
Fast, allocation-conscious resilience for .NET. Kevlar brings retries, circuit breakers, timeouts, rate limiting, concurrency limiting, hedging and fallbacks together in one fluent API.
Resilience code should explain how a call is protected, not make you decode a framework. With
Kevlar, you build an immutable Shield, reuse it, and use it with ordinary sync, Task or
ValueTask delegates.
Documentation · Strategies · Benchmarks
Get started
dotnet add package Kevlar
using Kevlar;
var shield = Shield
.Timeout(TimeSpan.FromSeconds(30))
.Retry(3)
.CircuitBreaker(5, breakDuration: TimeSpan.FromSeconds(30));
var user = await shield.ExecuteAsync(
ct => LoadUserAsync(id, ct), cancellationToken);
That reads in execution order: the 30-second timeout wraps the retries, which wrap the circuit
breaker. Retry(3) uses exponential backoff with jitter by default. The cancellation token passed
to your delegate is important—it is how timeouts and abandoned attempts stop the underlying work.
Build shields once and reuse them. They are immutable and thread-safe. Reuse also matters for stateful strategies: calls made through the same shield share its circuit breaker and limiter state.
Why Kevlar?
- The common case stays small. Start with
Shield.Retry(3); use options and callbacks when the situation genuinely needs them. - Failures can be exceptions or results. Retry an
HttpRequestException, an HTTP 500 response, or both, without changing the shape of the pipeline. - Composition is explicit. Chain strategies, or combine existing shields with
WrapandCompose. The first strategy is always the outermost. - It is designed for hot paths. Struct outcomes, pooled contexts, state-passing overloads and
ValueTaskkeep overhead and allocations low. The repository publishes comparative BenchmarkDotNet results. - Production concerns are built in. Shields support
TimeProvider, describe their own pipeline, and publish metrics through theKevlarmeter on .NET 8 and later. An optional analyzer catches cancellation and pipeline mistakes at compile time.
The core package targets netstandard2.0 and net10.0.
Choose what counts as failure
Reactive strategies handle any exception except OperationCanceledException by default. A
handling clause lets you be more precise:
var search = Shield.For<HttpResponseMessage>()
.When<HttpRequestException>()
.Or<TimeoutExceededException>()
.OrResult(response => (int)response.StatusCode is 429 or >= 500)
.Fallback((outcome, ct) => cache.GetCachedResultsAsync(ct))
.Retry(3)
.CircuitBreaker(5, TimeSpan.FromSeconds(30));
The clause applies to the reactive strategies that follow it. Typed shields keep result handling
strongly typed, including callback events and Outcome<T> values.
Compose protection in reading order
The first strategy is the outermost, just like ASP.NET middleware:
var shield = Shield
.Timeout(TimeSpan.FromSeconds(30)) // total budget
.Retry(3) // retry within that budget
.CircuitBreaker(5, TimeSpan.FromSeconds(30))
.Timeout(TimeSpan.FromSeconds(5)); // budget for each attempt
This rule makes the important questions visible: is a timeout per attempt or for the whole call?
Does fallback wrap retry? Are two clients meant to share one circuit? See
composition for Wrap, Compose and the
state-sharing rules.
HTTP and dependency injection
Kevlar.Extensions.Http provides a ready-to-use HttpClientFactory pipeline:
services.AddHttpClient("api")
.AddStandardShield();
The standard shield has a 30-second total timeout, three jittered retries that honour
Retry-After, a circuit breaker, and a 10-second timeout per attempt. You can configure every
part or supply your own shield. Kevlar.Extensions.DependencyInjection adds named,
configuration-bound shields and IKevlarRegistry.
Packages
| Package | What it adds |
|---|---|
Kevlar |
Core strategies and the Shield API |
Kevlar.Chaos |
Controlled latency, faults, outcomes and custom behaviour |
Kevlar.Extensions.DependencyInjection |
Named and configuration-bound shields for Microsoft DI |
Kevlar.Extensions.Http |
HttpClientFactory integration, request replay and transient-fault handling |
Kevlar.Extensions.Grpc |
gRPC client resilience for unary and streaming calls |
Kevlar.Extensions.RateLimiting |
Adapters for System.Threading.RateLimiting and custom leases |
Kevlar.Analyzers |
Compile-time checks for common resilience mistakes |
Kevlar.Testing |
Pipeline assertions, state snapshots and deterministic time helpers |
Where next?
- Follow the getting-started guide.
- Browse the strategy reference.
- Add HTTP resilience, dependency injection, or observability.
- Moving from Polly? The migration guide maps the concepts side by side.
| Product | Versions 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 is compatible. 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. |
-
.NETStandard 2.0
- Grpc.Core.Api (>= 2.83.0)
- Grpc.Net.ClientFactory (>= 2.83.0)
- Kevlar (>= 0.3.0)
- Kevlar.Extensions.DependencyInjection (>= 0.3.0)
-
net10.0
- Grpc.Core.Api (>= 2.83.0)
- Grpc.Net.ClientFactory (>= 2.83.0)
- Kevlar (>= 0.3.0)
- Kevlar.Extensions.DependencyInjection (>= 0.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.3.0 | 0 | 8/21/2026 |