Use pidstat to Find CPU, Memory and I/O Load by Process
Top shows you the busiest process right now, but pidstat lets you watch one known PID over time and break its load apart. The examples use sysstat 12.6.1, installed here as package version 12.6.1-2.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell, the sysstat package and a mounted /proc filesystem. The commands only read process statistics and normally need no elevated privileges. A process you can see may exit before a report is taken, so treat a missing row as a timing result rather than proof that the process never ran.
1. Check the installed command
Confirm which binary will run and record its version. This is a read-only checkpoint:
$ command -v pidstat
/usr/bin/pidstat
$ pidstat -V
sysstat version 12.6.1
(C) Sebastien Godard (sysstat <at> orange.fr)
The exact copyright line can vary. The version matters because the option set and output details belong to the installed sysstat release, not to a generic command named pidstat.
2. Take a bounded CPU snapshot
With no activity option, pidstat reports CPU activity. Give it an interval and a count so the command stops by itself:
$ pidstat 2 5
This takes five reports, two seconds apart, then exits. A typical report has columns such as %usr, %system, %wait, %CPU, CPU and Command. The command also prints an average report at the end. The first report describes activity since boot, while later reports describe the preceding interval, so do not compare the first row with the later rows as if they covered equal periods.
If you omit the count, the command continues until you interrupt it with Ctrl-C. If you omit both interval and count, it reports accumulated statistics since boot rather than sampling repeatedly:
$ pidstat
$ pidstat 1 1
Checkpoint
Use pidstat 1 1 when you need one quick, bounded sample. Use pidstat 2 5 when short-lived bursts are more likely to matter.
3. Focus on one process
Replace PID with the numeric process ID you want to inspect. The -p option selects it:
$ PID=12345
$ pidstat -p "$PID" 1 5
Set PID only after checking it belongs to the process you mean. For example:
$ ps -p "$PID" -o pid=,user=,comm=
12345 alice worker
$ pidstat -u -p "$PID" 1 5
- -u makes the CPU report explicit. A process can disappear between
psandpidstat; rerun the check with a current PID if that happens. - SELF and ALL are special targets.
SELFselects thepidstatprocess itself, andALLselects all tasks. Leaving out-pis similar to-p ALL, but only tasks with non-zero statistics appear.
4. Separate CPU pressure from memory pressure
Use -r for page faults and memory utilisation:
$ pidstat -r -p "$PID" 1 3
Linux 6.8.0-... (...)
... PID minflt/s majflt/s VSZ RSS %MEM Command
- minflt/s counts minor faults per second.
- majflt/s counts major faults per second.
- VSZ is the task's virtual size.
- RSS is its non-swapped physical memory.
- %MEM is its share of available physical memory.
A high VSZ alone does not mean the process is consuming that amount of RAM. Compare RSS and %MEM, then investigate the process before deciding that it is leaking memory.
To make a wider process scan easier to parse, filter by command name. The argument is a regular expression, not necessarily an exact name:
$ pidstat -r -C 'worker|renderer' -p ALL 1 3
Quote the expression so the shell does not reinterpret characters in it. A filter matching nothing is a useful result; do not broaden it blindly if the process has already exited.
5. Check disk I/O and task switching
Use -d for I/O counters:
$ pidstat -d -p "$PID" 1 5
Look at kB_rd/s, kB_wr/s, kB_ccwr/s and iodelay. The manual describes these as kilobytes per second and clock ticks, but notes that the displayed kB and related units are actually kibibytes and mebibytes. Keep that distinction in mind when comparing the output with tools that label binary units precisely.
For scheduling activity, use -w:
$ pidstat -w -p "$PID" 1 5
cswch/s is the voluntary context-switch rate, while nvcswch/s is the non-voluntary rate. These numbers are clues, not diagnoses. Compare them with CPU and I/O activity over the same interval.
6. Include threads or children deliberately
Use -t when the process is a multithreaded service and the process total hides the useful detail:
$ pidstat -t -u -p "$PID" 1 3
The output adds TGID for the thread-group leader and TID for the thread. A thread row is not another independent process, so avoid adding process and thread rows together as if they were separate workloads.
Use -T CHILD when you need aggregate statistics for selected tasks and their children:
$ pidstat -T CHILD -r -p "$PID" 1 3
Child statistics are collected when a child finishes or is killed, so they may not represent the current interval. -T ALL combines individual task rows with child aggregates. Choose -T TASK explicitly when you want the default individual-task view.
7. Make output safe for logs
Use -h for one horizontal line per report, with no average section, when another program will parse the output. Use -H when epoch timestamps are easier to correlate with logs:
$ pidstat -h -H -u -p "$PID" 1 3
Warning
Use -l when the short command name is not enough and you need the full command line, but that can expose arguments in saved logs, including tokens or other sensitive values. Check the destination's permissions before redirecting output, and do not capture command lines into a shared ticket or public paste without reviewing them.
If terminal formatting makes parsing unreliable, set the colour environment variable to never for that invocation:
$ S_COLORS=never pidstat -h -u -p "$PID" 1 3
Common traps
- Do not reach for sudo first. Check the PID, command filter, interval and process lifetime before an empty report makes you suspect permissions.
- Fix the mount, not the flags. The command needs
/proc; if that filesystem is not mounted, fix the host's normal mount configuration rather than guessing at flags. - Do not read one percentage as a full diagnosis. CPU figures can be divided by the processor count with
-I, which changes the interpretation on an SMP system; a report with-Iis not directly comparable with one without it. - -e launches and runs a program. The
-e PROGRAM ARGSform executes the supplied program and monitors it until it terminates, so do not paste unreviewed input into that form. For ordinary observation, select an existing PID instead.
No example in this guide changes a service, process policy or persistent configuration, so there is nothing to undo.
Done means
- Version confirmed: you confirmed the installed sysstat version and binary.
- Sampling bounded: you used a non-zero interval and count for bounded sampling.
- Target checked: you checked a target PID before collecting its CPU, memory or I/O data.
- Rows distinguished: you distinguished process totals, thread rows and child aggregates.
- Logs made safe: you used plain, timestamped output when saving reports for later parsing.
- Limits respected: you treated missing rows, first-report averages and unit labels as interpretation limits rather than errors.