Bulkhead Pattern in Practice
Bulkhead Pattern in Practice
The bulkhead pattern isolates resources so that failures in one component do not spread across the entire system. The name comes from ship compartments that prevent flooding from sinking the vessel.
Where Bulkheads Help
- Separate thread pools for external dependencies.
- Dedicated connection pools per database.
- Resource quotas per tenant or workload type.
Implementation Approaches
Thread Pool Isolation
Use separate executors per dependency to prevent a single slow service from exhausting all threads.
Semaphore Isolation
Limit concurrent calls to a dependency and return fast failures when the limit is exceeded.
Spring Boot + Resilience4j Bulkhead Example
1
2
3
4
5
6
7
@Bean
public BulkheadConfig paymentBulkheadConfig() {
return BulkheadConfig.custom()
.maxConcurrentCalls(20)
.maxWaitDuration(Duration.ofMillis(50))
.build();
}
1
2
3
4
5
6
7
@Bulkhead(name = "payment")
public Mono<PaymentStatus> getPaymentStatus(String id) {
return webClient.get()
.uri("/payments/{id}", id)
.retrieve()
.bodyToMono(PaymentStatus.class);
}
Capacity Planning
Bulkheads need capacity planning based on:
- Expected concurrency per dependency.
- Latency distribution and timeouts.
- Failure modes during overload.
Summary
Bulkheads create hard boundaries between dependencies. When combined with circuit breakers and timeouts, they are one of the most effective defenses against cascading failures.
This post is licensed under CC BY 4.0 by the author.