Resiliencemedium3-5 years

An orders service calls a slow, non-critical reporting service and a fast, critical payments service, both from the same shared thread pool. Why does a bulkhead around each matter, and which Resilience4j bulkhead type — semaphore or thread-pool — fits which?

A shared thread pool of, say, 200 threads serves every endpoint; if calls to the slow reporting service hold a lot of them waiting, the endpoint that only reads from the local database — needing nothing external — can't get a thread either, because they're the same pool. A bulkhead caps how much concurrency any one dependency's calls may consume. The semaphore bulkhead limits concurrent entries on the caller's own thread — simple, but the caller's thread is still held while blocked. The thread-pool bulkhead runs the call on its own dedicated pool and hands back a future, fully isolating it at the cost of a thread hop. Reporting, which the caller doesn't need to wait on, fits the thread-pool form; payments, fast and critical, fits a generously sized semaphore.

The lesson behind it →
More on Resilience