Bulkhead
Submarine-style watertight compartments applied to resource pools: prevent a failure from propagating.
Problem
An EDI hub talks to 200 partners over AS2, AS4, SFTP. If they all share one pool of 100 threads and 500 HTTP connections, a single misbehaving partner (30s latency per request) progressively saturates the pool and blocks the other 199. Outcome: an incident at a second-tier supplier brings down Walmart flows.
Forces
- Failures are not binary. A slow partner (no timeout) is worse than a down partner — it ties up live resources.
- Partner SLAs differ. Walmart demands 5s, a fourth-tier supplier accepts 30s — their flows must not share a pool.
- Over-allocation wastes. Granting 100% of capacity to every partner is impossible — a quota weighted by business volume is needed.
- Isolation has an observability cost. More pools = more metrics = more dashboards.
Solution
Slice the hub into isolated compartments: per critical partner (Walmart, Carrefour, Stellantis dedicated), per protocol type (AS2 separate from AS4 and SFTP), per business criticality (orders apart from invoices, apart from telemetry). Each compartment has its own thread pool, connections, memory budget, timeout — tuned to its SLA. A saturation remains local to the compartment.
┌──────────────┬──────────────┬──────────────┬──────────────┐ │ Walmart │ Carrefour │ Stellantis │ BNP │ │ thread-pool │ thread-pool │ thread-pool │ thread-pool │ │ 20 threads │ 20 threads │ 20 threads │ 10 threads │ │ 100 conn AS2│ 100 conn AS2│ 50 conn AS4 │ 20 conn SFTP│ └──────────────┴──────────────┴──────────────┴──────────────┘ Walmart down → its 20 threads blocked, but the other partners keep running at 100% capacity.
EDI implementation
Concrete case: in Sterling B2B Integrator, configure "Mailbox Groups"
per major partner, each with its own thread pool and timeout. On
Kubernetes, deploy a dedicated Walmart Pod, another for Carrefour,
scaled independently. On Kafka, create a topic edi.in.walmart separate from edi.in.carrefour,
each consumed by a dedicated consumer group. On the API gateway,
apply a rate-limit per partner key: if Walmart consumes
its quota, it does not affect Carrefour.
Anti-patterns
- Shared global pool. One thread pool for all partners: a single failure contaminates everything.
- Compartments without timeout. Perfect isolation, but threads in a compartment block forever on a dead partner.
- Too many compartments. One compartment per partner for 5,000 partners: unmanageable operational overhead. Group non-critical partners.
- Bulkhead without observability. Without per-compartment metrics, local saturation is invisible: the isolation is silent.
Related patterns
- Circuit Breaker — often combined, one per compartment.
- Back-pressure — upstream throttling, complementary to isolation.
- Rate Limiter — typically applied per compartment.
Sources
- Nygard M. — Release It! Design and Deploy Production-Ready Software, Pragmatic Bookshelf 2018 (2nd ed.), chap. "Bulkheads". The canonical reference for the pattern.
- Microsoft Architecture Center — Bulkhead pattern. learn.microsoft.com — Bulkhead
- Netflix — Hystrix. Historic implementation of Bulkhead + Circuit Breaker (deprecated, but pedagogical reference). github.com/Netflix/Hystrix — Bulkhead
- Resilience4j — Bulkhead module. The modern Java implementation of the pattern. resilience4j.readme.io/docs/bulkhead