A service company starts an annual export of customer cases. The export is still running, and employees can no longer open an ordinary case. Nobody changed the case-screen code. The export simply occupied the database connections and workers shared by the rest of the application.
Adding application instances will not necessarily help. If each new instance sends more work to the same database, contention for the limited resource can get worse. First identify the workflow that must remain available and the neighbouring workload capable of preventing it.
Separate menu items are not isolated resources
A bulkhead separates capacity between types of work. Exports may have their own bounded worker group while interactive requests use another. Calls to a slow external provider can have a separate connection pool so they do not consume every connection available to the application.
This does not automatically require another microservice. Separate pools or a limit on concurrent dependency calls inside one application may be sufficient. Other failures require isolation at process, container or infrastructure level. The choice depends on the resource being exhausted and the failure the company needs to contain.
Those levels provide different protection. Separate workers can limit task concurrency without isolating a process's memory. Two containers on one host still share underlying capacity. Independent applications accessing one database may simply meet in a queue there instead. Drawing separate boxes does not remove these dependencies.
A workload limit is not the same as reserved capacity
Restricting the number of simultaneous exports is useful, but it does not guarantee a responsive case screen. Each permitted export may scan a large dataset or hold disruptive locks. The design must account for the cost of individual operations and shared database, storage and network limits.
If a critical journey needs protected capacity, explain how that capacity remains available. It may be a separate pool combined with limits on neighbouring workloads, or a deeper separation of execution. A counter on one feature is not sufficient evidence of a real reservation.
Requests-per-second limits are not enough on their own either. When a dependency slows down, an unchanged arrival rate can leave more operations waiting concurrently. Rate and concurrency controls address different dimensions of demand.
Count the entire deployment as well. A separate connection pool in every application instance increases the potential connection total as the application scales. A safe setting for one process does not prove that the shared database can support all processes together.
What happens to work that does not fit?
An export can wait in a queue. An unbounded queue, however, turns an explicit rejection into a promise the system may never fulfil. Accepted work needs a limit, an expiry policy and a status the employee can understand.
For an interactive case screen, a long queue is especially unhelpful: the employee may leave before a worker becomes available. A short bounded wait followed by a clear rejection may be preferable. Freed capacity should not be spent on requests whose deadlines have already expired.
Retries must respect the same boundaries. Otherwise the original workload is constrained while recovery attempts get an unlimited bypass. A fallback that accesses the shared database directly can undermine isolation in the same way.
This is where bulkheads meet backpressure: the system stops admitting additional work or asks the sender to slow down. Splitting pools does not reduce incoming demand by itself.
A large customer can still monopolise the export pool
In a multi-tenant product, one customer may submit enough expensive jobs to occupy the entire export allocation. Interactive work is protected, but other customers still cannot get their reports. The first boundary solved only part of the problem.
Options include per-customer job limits, scheduling across customer groups and dedicated capacity for unusually demanding workloads. A separate infrastructure deployment for every tenant is not mandatory. The important point is that priority and acceptable waiting times match what the product promises.
Background work also has obligations. If interactive traffic always receives every available resource, synchronisation or required exports may never finish. Priority needs an accompanying policy for how less urgent work eventually receives a share.
The cost is visible even on a quiet day
With strict partitioning, one allocation can sit idle while another is saturated. That is not automatically a defect: the spare capacity was reserved to protect a particular workflow. Its cost should nevertheless be compared with the consequences of losing that workflow, rather than hidden under the label of reliability.
Borrowing idle capacity dynamically can improve utilisation, but it complicates the promise. When the protected workload needs its allocation back, long-running jobs may not release it immediately. Reclaim behaviour must be tested rather than assumed.
Each boundary also adds configuration and monitoring: concurrency, queue limits, timeouts and an owner. A simple workload may be adequately protected by a shared limit and sensible deadlines. Dozens of small pools without a clear purpose make operation harder without establishing useful protection.
Prove that the case screen remains usable
Run the permitted number of heavy exports together, then slow down their database or external dependency. At the same time, open and update ordinary cases. Measure the duration and success of those employee actions, not merely whether application processes remain alive.
Inspect queue limits, rejected work, the oldest queued job and utilisation at every shared layer. Then remove the overload. The backlog should drain at a controlled rate rather than produce a second surge. If the interactive workflow still fails, the test has identified a concrete shared resource that the current isolation does not yet protect.