Post

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.