Fictional teaching example. It does not describe a particular organisation or incident.
Situation
An application processes orders and generates reports. Calls to both external services use the same connection pool and queue. When reporting slows down, its requests occupy the workers. Orders begin to wait, even though their own dependency is healthy.
Where the anti-pattern appears
The configuration assumes sharing resources has no cost. The lower priority of reports is not reflected in technical limits. A slowdown in one dependency consumes the time and concurrency budget of the others. Doubling the common pool might briefly shorten the queue; the problem returns under another traffic spike.
Warning signs
- Critical and optional calls use one unbounded queue.
- One timeout applies to operations with different service objectives.
- Metrics show only total connections, with no per-dependency view.
- During a provider failure the team increases pool size and retries without testing the impact on other features.
A better decision
- Identify which functions must continue when other dependencies fail, and give each a time budget.
- Add separate concurrency limits, pools or queues where isolation matches that boundary. Size them with measurements.
- Decide what happens when a limit is reached: reject new work, defer it, or return a partial result. Make the outcome clear to the user.
- Measure saturation for each segment and exercise a slowdown under load.
Isolation costs capacity: idle resources in one pool may not be available to another. Compare this cost with the price of a shared failure. A small system does not automatically need many pools; priorities and measurements should drive the choice.
Rule to remember
If functions must survive different failures, sharing their resource pool needs an explicit justification.
Discuss this article
Share a constructive observation or an anonymised example. Comments are checked by AI before publication. Uncertain cases go to the moderator.