Bottleneck

Also known as: performance bottleneck

On this page 7

A bottleneck (or performance bottleneck) is the resource or component with the lowest effective capacity in a processing path, which therefore limits the throughput and response time of the whole system. In server performance it may be CPU, memory, disk, network, a pool of application workers, a database lock or an external API, and improving any other part brings little benefit until the bottleneck itself is relieved.

The concept comes from the narrow neck of a bottle: however wide the body, liquid flows only as fast as the neck allows. In a server stack, requests pass through several stages in sequence, and the slowest stage sets the pace for everything behind it.

How a bottleneck limits throughput

A server handles a request by moving it through a chain of resources: the network accepts it, a web server passes it to a PHP worker pool or application runtime, the code queries a database and the response travels back. Each stage has a maximum service rate, and the system throughput cannot exceed the rate of its slowest stage.

As load approaches that limit, the bottleneck reaches resource saturation. Requests then start to queue, and queueing theory explains why response time rises sharply rather than linearly: once a resource is busy most of the time, waiting time grows steeply with every additional request. Utilization of about 70 to 80 percent on the constrained resource is a common point where latency begins to climb noticeably.

The table below shows how the same workload behaves before and after the bottleneck saturates.

Load levelBottleneck utilizationThroughputResponse time
LightBelow 50 percentGrows with loadStable
Moderate50 to 80 percentStill growsRises gradually
Near saturation80 to 95 percentFlattensRises steeply
Overload100 percentFlat or fallingTimeouts and errors
Typical behavior as load approaches the bottleneck

Common types of server bottlenecks

Server bottlenecks fall into a few recurring categories, each with its own telltale signals. Identifying the category first narrows the investigation considerably.

Bottleneck typeTypical signalsCommon cause
CPUUtilization near 100 percent, rising run queueUncached dynamic pages, heavy code
MemorySwap activity, out-of-memory killsToo many workers for available RAM
Disk I/OHigh I/O wait, long device latencyRandom writes, missing indexes
NetworkSaturated link, retransmissionsLarge uncompressed responses
Worker poolRequests queue while CPU is idlePool too small or slow external calls
DatabaseSlow queries, lock waitsMissing indexes, long transactions
Bottleneck types and their usual signals

Not every bottleneck is a hardware resource. A software limit, such as a maximum connection count, a single-threaded process or a global lock, can cap throughput while CPU and memory remain mostly idle. These logical bottlenecks are often the hardest to find because standard resource graphs look healthy.

A bottleneck is a location in the system, whereas throughput, response time and saturation are measurements of system behavior. Keeping the distinction clear avoids treating symptoms as causes.

TermWhat it describesRelation to a bottleneck
ThroughputWork completed per unit of timeCapped by the bottleneck
Response timeTime to complete one requestGrows as the bottleneck saturates
Resource saturationA resource with work queuedThe state a bottleneck reaches
Requests per secondA common throughput measureShows the ceiling, not its cause
Server-side cachingReusing computed resultsA way to remove a bottleneck
How a bottleneck relates to neighboring terms

A system usually has exactly one dominant bottleneck at a given load, but it can move as the traffic mix changes. A site may be CPU-bound during cache misses after a deployment and database-bound during reporting jobs, so the analysis must always state the conditions under which the bottleneck was measured. Cache warming after a release is one way to prevent a temporary CPU bottleneck from reaching visitors.

Finding and removing a bottleneck

Bottleneck analysis follows a measure, locate, fix and re-measure cycle. The USE method, which checks utilization, saturation and errors for every resource, is a systematic way to cover the whole server without guessing.

  1. Reproduce the load with a load test or observe real peak traffic.
  2. Collect metrics per stage, including CPU, memory, I/O, network, worker pool queues and query times.
  3. Find the first saturated resource, the one with queues or errors as load rises.
  4. Apply one change at a time, such as adding cache, capacity or an index.
  5. Measure again, because removing one bottleneck exposes the next one.

Typical remedies depend on where the limit sits. The table below pairs common situations with effective first responses.

SituationFirst remedyWhy it helps
CPU-bound PHP pagesEnable OPcache and a full-page cacheAvoids repeated compilation and rendering
Repeated database queriesAdd an object cacheServes results from memory
Slow single queryAdd an index or rewrite the queryReduces rows scanned
Large static responsesEnable Gzip or Brotli compressionCuts bytes on the network
Exhausted worker poolTune pool size to available RAMMatches concurrency to capacity
Typical remedies by bottleneck location

Common mistakes in bottleneck analysis

Most failed tuning efforts share a handful of avoidable mistakes.

  • Optimizing a non-bottleneck, such as tuning CPU usage when the database lock is the real limit.
  • Relying on averages, which hide short saturation peaks and slow outlier requests.
  • Adding hardware blindly, which helps only if the added resource is the constrained one.
  • Changing several settings at once, which makes it impossible to tell what worked.
  • Ignoring the shifting bottleneck: after a fix, a different resource usually becomes the new limit.

A plain-language summary

Think of a highway where four lanes narrow to one lane at a bridge. Cars move quickly before the bridge, but traffic can never pass faster than the single lane allows. Widening the road elsewhere changes nothing.

A server works the same way. A bottleneck is its narrowest point, such as a slow disk or too few workers. To make the server faster, you first find that narrow point and widen it. Then you check where the next narrow point appears.

An example from practice

An online store on a server with 4 CPU cores and 8 GB of RAM starts returning slow pages during a seasonal sale. Response time rises from about 300 ms to more than 4 seconds, yet the CPU sits at only 40 percent. The administrator notices that all 10 PHP workers are busy and requests are waiting in the queue.

Further profiling shows that each checkout page waits about a second for a slow shipping-rate API. The workers are not computing; they are blocked waiting on an external call. The team caches shipping rates for common destinations and adds a short timeout. Workers are freed quickly, the queue disappears and response time returns to under 500 ms at the same traffic level, without any hardware change.