NS-065
documentedaverage-presented-as-current
The %CPU column is a lifetime average, not a current rate
- reads as
- `ps aux` shows one process at 85.1% CPU. Conclusion drawn: this is the process consuming the machine now.
- actually
- ps(1) states it plainly: 'CPU usage is currently expressed as the percentage of time spent running during the entire lifetime of a process.' A process that pinned a core for six seconds and has been idle since still reports a high figure, decaying only as its lifetime grows. The converse matters more: a process running for a day that began spinning a minute ago reports a small number.
- blind because
- The column has the units of a rate and is read as one. Nothing in the output records the averaging window, which is each process's own age and therefore different in every row.
- the check
- Measure the delta over a known interval: read fields 14 and 15 of /proc/PID/stat twice and divide the difference by CLK_TCK times the elapsed seconds. Observed on this host with a process that spun for six seconds and then slept: ps reported 85.1% immediately afterwards and 22.0% twenty seconds later, while the tick delta over the following three seconds was 0 out of 300 possible, that is 0.0% actual.
- cost of missing
- The wrong process is restarted, throttled or blamed, and the one that has quietly started to spin is ranked below it because its long life dilutes its average.
- mitigation
- top's %CPU is an interval rate rather than a lifetime average, and pidstat reports per-interval figures directly.
- generalises to
- Every statistic whose window is implicit: lifetime averages, cumulative counters presented as gauges, uptime-normalised error rates.
- source
- man7.org