Resource saturation

On this page 7

Resource saturation is the condition in which a server resource receives more work than it can service, so the excess waits in a queue. In server performance analysis, saturation is measured by the length of that queue or the time spent waiting, and it is the point at which additional load stops increasing throughput and starts increasing latency instead.

Saturation can affect any finite resource: CPU cores, memory, disk I/O, network links, and software resources such as connection pools and PHP worker pools. Recognizing which resource saturates first is the core of capacity planning and of most performance troubleshooting.

How saturation differs from utilization

Utilization describes how busy a resource is, usually as a percentage of time it was working. Saturation describes how much work is waiting because the resource is busy. A disk can be 100 percent utilized with a queue of one request, or with a queue of fifty, and only the second case means severe saturation.

Queueing theory explains why saturation appears before utilization reaches 100 percent. In a simple single-server queue, the average response time grows roughly in proportion to 1 divided by (1 minus utilization). At 50 percent utilization, response time is about twice the service time; at 90 percent it is about ten times the service time, and small load spikes then create long queues.

This is why experienced operators treat sustained utilization above about 70 to 80 percent on latency-sensitive resources as a warning sign. The exact threshold depends on how variable the arriving work is: bursty traffic saturates sooner than smooth traffic at the same average load.

Saturation signals for each server resource

Each resource exposes saturation through its own queue metric. The widely used USE method checks utilization, saturation and errors for every resource in turn, and the table lists the saturation part for the main resources of a Linux server.

ResourceSaturation metricTypical toolWarning sign
CPURun queue length, load average per corevmstat, uptimeRunnable tasks above core count for minutes
MemorySwap activity, page reclaim, OOM killsvmstat si/so, dmesgContinuous swapping or OOM events
Disk I/OAverage queue size, await timeiostat -xAwait far above device service time
NetworkDropped packets, retransmits, socket backlogss, netstat -sRising drops or listen overflows
All of the abovePressure stall information/proc/pressure/*Sustained some or full stall percentages
Where saturation shows up on a Linux server

Pressure stall information, available in modern Linux kernels, reports the share of time tasks were delayed waiting for CPU, memory or I/O. It measures saturation directly as lost time, which makes it easier to interpret than raw queue lengths.

Software resources that saturate

Hardware is often not the first bottleneck. Software limits such as worker counts and pool sizes cap concurrency deliberately, and when they are reached, requests wait even though CPU and memory still have headroom.

Software resourceLimit settingSaturation symptomUsual remedy
PHP worker poolpm.max_children in PHP-FPMListen queue grows, max children reached warningRaise children if memory allows, speed up scripts
Database connection poolPool maximum sizeThreads wait for a free connectionShorten transactions, size pool to database capacity
Web server workersMaxRequestWorkers or worker connectionsAccept queue fills, timeoutsAdd workers or offload static content
File descriptorsulimit -n, LimitNOFILEToo many open files errorsRaise limit and fix leaks
Thread or event loopPool threads or single loopEvent loop lagMove blocking work off the loop
Saturation of common software resources

Raising a software limit only moves the queue elsewhere. Doubling pm.max_children without enough memory replaces queueing in PHP-FPM with swapping, and enlarging a connection pool beyond what the database can handle shifts saturation to the database server.

Effects on throughput and latency

As load increases toward saturation, throughput grows linearly and then flattens at the capacity of the bottleneck resource. Beyond that point, every extra request only adds waiting time, so tail latency at the 95th and 99th percentile rises much faster than the average.

Load regionThroughputLatencyOperational meaning
Well below capacityRises with loadStable, close to service timeHealthy headroom
Approaching saturationStill rising, slowerTail latency climbsPlan capacity or optimize
SaturatedFlat at maximumGrows with queue lengthUsers feel slowness
OverloadedMay fall below maximumTimeouts and errorsRetries amplify the problem
Typical behavior across load regions

Severe overload can even reduce throughput. Clients time out and retry, so the server performs the same work several times, and processes waste effort on context switches or memory reclaim. Protective measures such as bounded queues, load shedding and rate limiting keep a saturated system productive.

Diagnosing and preventing saturation

Diagnosis starts by finding the resource with the longest wait, not the one with the highest utilization. A server with 40 percent CPU and a deep disk queue is limited by storage, and adding CPU cores will not help.

  • Monitor saturation metrics alongside utilization, not utilization alone.
  • Load test to find the knee of the latency curve before production traffic does.
  • Set bounded queues and timeouts so that overload fails fast instead of piling up.
  • Size pools from measured per-worker memory and backend capacity, not from defaults.
  • Watch averages carefully, because one-minute averages can hide seconds of saturation.

Short bursts of saturation are normal and harmless when queues drain quickly. Sustained saturation, visible over minutes in queue lengths and tail latency, is the signal that capacity, configuration or code needs attention.

Stripped to the essentials

Think of a supermarket with four checkouts. When few shoppers arrive, everyone pays immediately. As the store fills up, lines start to form, and soon each extra shopper mainly adds waiting time rather than more sales per minute.

A server works the same way. Saturation is the moment lines start forming in front of its processor, disks, memory or worker processes. The fix is to find which checkout has the longest line and add capacity there, or make each customer faster to serve.

Where it is applied

A WordPress site on a virtual server with 8 GB of memory and four vCPUs becomes slow every weekday morning, although monitoring shows CPU utilization of only about 55 percent. Pages that normally load in 300 milliseconds take several seconds.

The PHP-FPM log contains repeated warnings that the pool reached pm.max_children, set to 10, and the status page shows a listen queue of more than 40 requests. Each PHP worker uses about 120 MB, so the server can afford roughly 30 workers while leaving memory for the database and cache.

The administrator raises the limit to 28, enables OPcache with enough memory to avoid recompilation, and adds an alert on the listen queue. Morning latency returns to under 400 milliseconds, and CPU utilization rises to about 75 percent, which shows that the bottleneck was a saturated worker pool rather than the processor.