Borrowed from ships
A ship hull is split into bulkheads so a breach floods one compartment, not the whole vessel. The same pattern isolates resources so one failing dependency cannot exhaust everything.
The shared pool problem
If every outbound call shares one thread pool, a single slow dependency can occupy all threads. Healthy calls then queue behind the slow one and the whole service stalls. This is cascading resource exhaustion.
Pool per dependency
The bulkhead gives each dependency its own bounded pool or a permit semaphore:
- Calls to a slow service can only use that service allotment.
- When its pool is full, new calls fail fast instead of borrowing from others.
- Other dependencies keep their own healthy threads.
Sizing and tradeoffs
Partitioning reduces total utilization because pools cannot share spare capacity. You trade some efficiency for containment. Size each pool from the dependency latency and the load you must absorb.
Key idea
Bulkheads give each dependency its own bounded pool, so a slow service exhausts only its compartment and the rest of the system stays afloat.