Bulkhead isolation strategy for Polly v8 resilience pipelines. Limits concurrent executions and queued actions, rejecting excess calls with BulkheadRejectedException.
Polly v8 replaced the v7 BulkheadPolicy with the more general RateLimiter strategy. This package restores the familiar bulkhead semantics — explicit max concurrency and max queue depth — as a first-class Polly v8 resilience strategy.
dotnet add package Polly.Contrib.Bulkhead
using Polly.Contrib.Bulkhead;
var pipeline = new ResiliencePipelineBuilder()
.AddBulkhead(maxConcurrency: 10)
.Build();
await pipeline.ExecuteAsync(async ct => await CallDownstreamAsync(ct), cancellationToken);var pipeline = new ResiliencePipelineBuilder()
.AddBulkhead(maxConcurrency: 10, maxQueuedActions: 20)
.Build();Calls beyond the 10 concurrent slots queue up. If the queue also fills (>20 waiting), further calls throw BulkheadRejectedException.
var pipeline = new ResiliencePipelineBuilder()
.AddBulkhead(new BulkheadStrategyOptions
{
MaxConcurrency = 10,
MaxQueuedActions = 20,
OnBulkheadRejected = args =>
{
logger.LogWarning("Bulkhead rejected call for {Operation}", args.Context.OperationKey);
return ValueTask.CompletedTask;
},
})
.Build();var pipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
.AddBulkhead<HttpResponseMessage>(maxConcurrency: 5)
.AddRetry(...)
.Build();| Scenario | Outcome |
|---|---|
| Slots available | Executes immediately |
| Slots full, queue not full | Waits in queue |
| Slots full, queue full | Throws BulkheadRejectedException |
No queuing (MaxQueuedActions = 0) |
Rejects immediately when at capacity |
Place bulkhead before retry so rejected calls don't get retried:
var pipeline = new ResiliencePipelineBuilder()
.AddBulkhead(maxConcurrency: 10) // 1. limit concurrency first
.AddRetry(...) // 2. retry transient failures
.AddCircuitBreaker(...) // 3. protect downstream
.Build();If Polly.Contrib.Bulkhead helps protect your services, consider supporting the project:
💼 Need .NET resilience help? Visit solidqualitysolutions.com for consulting and architecture services.
| Package | Downloads | Description |
|---|---|---|
| PollyHealthChecks | ASP.NET Core health checks for Polly v8 circuit breakers — expose circuit-breaker state (Closed, HalfOpen, Open, Isolated) as /health endpoint responses | |
| PollyOpenTelemetry | OpenTelemetry instrumentation for Polly v8 resilience pipelines | |
| PollyBackoff | Backoff delay strategies for Polly v8 resilience pipelines | |
| PollyGrpc | Polly v8 resilience interceptor for gRPC | |
| PollyEFCore | Polly v8 resilience pipelines for Entity Framework Core — wrap every EF Core query and SaveChanges with retry, timeout and circuit-breaker via a single AddPollyResilience() call | |
| PollyRabbitMQ | Polly v8 resilience for RabbitMQ.Client v7+ — retry, circuit-breaker, and timeout for IChannel operations, with built-in RabbitMqTransientErrors predicate covering AlreadyClosedException, BrokerUnreachableException, OperationInterruptedException, and ConnectFailureException | |
| PollyOpenAI | Polly v8 resilience for OpenAI and Azure OpenAI API calls | |
| PollySignalR | Polly v8 reconnect policy for SignalR | |
| PollyMediatR | Polly v8 resilience pipelines for MediatR — add retry, timeout, circuit-breaker, rate-limiting, hedging, and chaos engineering to any MediatR request handler with a single line of DI registration | |
| PollyRedis | Polly v8 resilience for StackExchange.Redis | |
| PollyAzureServiceBus | Polly v8 resilience for Azure Service Bus — retry, circuit breaker, and timeout for sending and receiving messages | |
| PollyKafka | Polly v8 resilience for Confluent.Kafka — retry, circuit breaker, and timeout for producers and consumers | |
| PollyRateLimiter | Convenience extension methods for Polly v8 resilience pipelines: AddFixedWindowRateLimiter, AddSlidingWindowRateLimiter, and AddTokenBucketRateLimiter | |
| PollyCaching | A caching resilience strategy for Polly v8 pipelines | |
| PollyChaos | Chaos engineering and fault-injection resilience strategies for Polly v8 pipelines |
| Package | Description |
|---|---|
| AutoLog.Generator | Compile-time high-performance logging — [Log(Level, Message)] generates LoggerMessage.Define. AOT-safe. |
| AutoHttpClient.Generator | Compile-time typed HTTP client — [HttpClient] on an interface generates a strongly-typed client. AOT-safe Refit alternative. |
| AutoDispatch.Generator | Compile-time CQRS dispatcher — [Handler] generates a strongly-typed IDispatcher. MediatR alternative. |
| AutoWire | Compile-time DI auto-registration — [Scoped]/[Singleton]/[Transient] generates IServiceCollection registration code. |
| AutoMap.Generator | Compile-time object mapping — [Map(typeof(Dto))] generates ToDto() extension methods. AutoMapper alternative. |
MIT