Finding the Real Bottleneck: Optimize the Constrained Path
📑 On this page
- A concrete example: adding web servers
- Throughput and latency
- End-to-end measurement
- Critical path
- Service demand
- Saturation
- Queueing
- Workload matters
- Averages hide tails
- Distributed tracing
- Profiling
- Database analysis
- Load tests
- Controlled experiments
- Coordinated omission
- Removing one bottleneck
- Caching
- Batching
- Cost bottlenecks
- Capacity models
- Optimization guardrails
- Knowledge check
- The one idea to remember
When a system feels slow, many components look improvable.
Web servers use CPU, queries scan rows, network calls take time, and queues contain work. Improving a component that is not limiting the outcome may produce no visible benefit.
A bottleneck is the resource or stage currently constraining end-to-end throughput or latency.
Measure the full path before deciding where to optimize.
A concrete example: adding web servers
Checkout latency is high, so a team doubles the number of web servers.
Nothing improves. Traces show every request waits on one database lock. Extra web servers create more concurrent waiters and increase connection pressure.
The database contention, not web compute, is the current bottleneck.
Throughput and latency
Throughput measures completed work per time.
Latency measures time for one operation.
The same constraint can affect both, but not always equally. A queue may preserve throughput while increasing waiting latency.
Define which outcome needs improvement.
End-to-end measurement
Break the user path into stages:
- client,
- network,
- edge,
- application,
- dependency,
- database,
- queue,
- rendering.
Measure time and waiting at each stage. Local microbenchmarks cannot reveal remote queueing.
Critical path
The critical path is the chain of work determining total completion time.
Parallel tasks do not simply add:
total ≠ task A + task BIf A and B run together, the slower branch may dominate before later work continues.
Traces reveal this shape.
Service demand
Estimate how much of each resource one unit of work consumes:
- CPU milliseconds,
- database queries,
- disk reads,
- network bytes,
- lock duration.
Multiplying demand by arrival rate indicates which resource approaches capacity.
Saturation
A resource is saturated when demand approaches or exceeds what it can serve.
Signals include:
- CPU run queue,
- database connection wait,
- disk queue,
- thread-pool exhaustion,
- memory pressure,
- queue age,
- and rate-limit rejection.
High utilization alone is not always harmful if latency remains stable.
Queueing
As utilization nears capacity, waiting can rise sharply.
Small demand variation creates large latency tails because new work waits behind existing work.
Measure queue time separately from execution time.
Workload matters
A bottleneck belongs to a workload:
- read-heavy browsing,
- write-heavy sale,
- large report,
- cache cold start,
- or regional failover.
An optimization for one workload can hurt another. Reproduce representative traffic and data.
Averages hide tails
Average latency can remain acceptable while p99 becomes terrible.
Tail requests may share:
- one large tenant,
- cold cache,
- rare query shape,
- overloaded shard,
- or distant region.
Segment metrics by meaningful dimensions.
Distributed tracing
Traces show:
- span duration,
- parent-child relationship,
- parallel work,
- retries,
- and dependency calls.
Sampling should preserve slow and failed traces.
Trace duration still needs resource metrics to explain why a span was slow.
Profiling
CPU profiles show where execution time is spent inside a process.
Memory profiles identify allocation and retention.
Use profiling after evidence points to the process. Profiling an idle web server will not explain database lock contention.
Database analysis
Inspect:
- slow-query fingerprints,
- execution plans,
- lock waits,
- index use,
- buffer hit rate,
- connections,
- and replication lag.
One query may be fast alone but destructive under concurrency.
Load tests
Increase load gradually while observing:
- throughput,
- latency,
- errors,
- and resources.
The saturation point shows where throughput stops growing and latency rises.
Test correctness as well as speed.
Controlled experiments
Change one meaningful factor:
- index,
- instance size,
- cache policy,
- concurrency,
- or batch size.
Compare against baseline under the same workload.
Changing several factors at once hides which one mattered.
Coordinated omission
A load generator that waits for slow responses may send less traffic during failure.
It underreports requests real users would continue producing.
Use arrival-rate-aware tools where appropriate.
Removing one bottleneck
After improving the current constraint, another becomes limiting.
This is normal. Performance work is iterative:
- measure,
- identify,
- improve,
- verify,
- repeat.
There is no permanently bottleneck-free system.
Caching
Caching can remove repeated expensive work.
It can also shift the bottleneck to:
- cache memory,
- invalidation,
- miss storms,
- or origin refill.
Measure hit ratio and miss cost, not cache presence alone.
Batching
Batching amortizes fixed cost across several items.
It may increase waiting while the batch fills and create large failure units.
Choose batch size using throughput and deadline evidence.
Cost bottlenecks
The limiting constraint can be budget or quota rather than hardware.
Examples:
- external API limit,
- cloud cost ceiling,
- licensing,
- or rate-limited partner.
Architecture should optimize the scarce business resource.
Capacity models
A simple capacity model records for each important operation:
- arrival rate,
- service time,
- concurrency,
- resource demand,
- and maximum useful wait.
The model does not need perfect prediction. It exposes assumptions, such as one checkout using four database queries, so measurements can show which assumption changed as traffic and features evolve.
Optimization guardrails
Performance changes must preserve:
- correctness,
- durability,
- security,
- and maintainability.
Removing a transaction or validation step can produce a faster benchmark while making the product unsafe. Define functional and resource guardrails before comparing results.
Knowledge check
- Why can adding web servers make database contention worse?
- What does the critical path determine?
- Why should queue time be measured separately?
- How do profiling and end-to-end tracing serve different purposes?
- Why does a new bottleneck appear after optimization?
The one idea to remember
Performance improves when engineers measure the complete workload path and change the resource or stage actually limiting the target. Use traces, resource saturation, queueing, profiles, database evidence, and controlled load tests before optimizing.