Bulkhead
Isolate resources so one overloaded dependency can't sink the whole ship.
By the end of this lesson, partition resource pools so a failure in one area can't starve the others.
Named after a ship's watertight compartments: if one floods, the others keep the ship afloat. A bulkhead partitions resources — separate thread pools, connection pools, or instances per dependency or tenant — so that saturating one partition can't consume the resources the others need.
First, see the whole system. Then we’ll open it up.
Isolated pools
- Each dependency gets its own pool; a slow Dependency A drains only Pool A, leaving B unaffected.
flowchart TB req[Requests] --> pa[Pool A -> Dependency A] req --> pb[Pool B -> Dependency B] pa -.slow.-> pa pb --> ok[B unaffected]
You know what happens. Now see why it works.
It stops the exact mechanism behind cascading failure: shared resource exhaustion. If every outbound call shares one thread pool, one slow dependency drains it and everything fails together. Per-dependency bulkheads confine that damage.
Isolation costs efficiency: dedicated pools can't share spare capacity, so you provision more headroom overall. You trade some utilization for the guarantee that one failure stays contained.
Why isolate pools per dependency instead of sharing one big pool?
A shared pool lets one slow dependency drain everything; isolated pools confine exhaustion to the failing dependency.