| Tested on | Rocky Linux 10.2 |
|---|---|
| Package | sysstat 12.7.6sysstat 12.7.6 |
| Applies to | Ubuntu, Debian, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux, SUSE, openSUSE, Alpine |
| Privilege | sudo or root |
| Man page | pidstat(1) |
| Scope | pidstat from the sysstat package reports per-process and per-thread CPU, memory, disk I/O, and context-switch statistics on Linux. Use it to find which PID is driving load during an incident. |
| Related guides | mpstat command cheat sheet iostat command cheat sheet vmstat command cheat sheet sar command cheat sheet iotop |
pidstat is part of the sysstat toolkit. It reports CPU, memory, disk I/O, context switches, and scheduling details for individual tasks (and optionally their threads or children). When global CPU looks busy but you need the owning PID, pidstat is usually faster than parsing top.
pidstat — quick reference
Default CPU report and intervals
| When to use | Command |
|---|---|
| Per-task CPU since boot (active tasks only) | pidstat |
| Sample every N seconds until Ctrl+C | pidstat N |
| N samples at M-second intervals | pidstat M N |
| CPU report explicitly | pidstat -u |
| Show sysstat version | pidstat -V |
Task selection and scope
| When to use | Command |
|---|---|
| All tasks including idle ones | pidstat -p ALL |
| One PID | pidstat -p 1234 |
| Several PIDs | pidstat -p 1234,5678 |
Monitor the pidstat process itself |
pidstat -p SELF |
| Match individual task command names with a regex | pidstat -C 'sshd' |
Match processes and include all their threads with -t |
pidstat -G 'systemd' -t |
| Limit to a user's tasks | pidstat -U root |
| Show full command line | pidstat -l -p PID |
Include threads (TGID / TID) |
pidstat -t |
| Include reaped child CPU time | pidstat -T CHILD -p PID |
| Task plus children totals | pidstat -T ALL -p PID |
| Run a command and sample it every second | pidstat 1 -e sleep 5 |
Resource reports
| When to use | Command |
|---|---|
| Per-process disk I/O | pidstat -d |
| Page faults and memory (RSS, VSZ) | pidstat -r |
| Voluntary and involuntary context switches | pidstat -w |
| Stack reservation and usage | pidstat -s |
| Thread and file-descriptor counts | pidstat -v |
| Realtime priority and scheduling policy | pidstat -R |
| CPU, memory, and I/O together | pidstat -dur |
Output format
| When to use | Command |
|---|---|
| Divide CPU % by processor count (SMP) | pidstat -I |
| Epoch timestamp column | pidstat -H 1 3 |
| Put all selected reports on one row per task | pidstat -h 1 3 |
| Integer percentages | pidstat --dec=0 |
| Human-readable I/O sizes | pidstat --human -d |
pidstat — command syntax
Synopsis from sysstat 12.7.6:
pidstat [ -d ] [ -H ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [ username ] ]
[ -u ] [ -V ] [ -v ] [ -w ] [ -C comm ] [ -G process_name ]
[ --dec={ 0 | 1 | 2 } ] [ --human ]
[ -p { pid[,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]
[ interval [ count ] ] [ -e program args ]With no activity flag, pidstat prints the CPU report (-u). Without -p, only tasks with non-zero statistics appear; -p ALL lists every task. Install with sudo dnf install sysstat on RHEL-family hosts or sudo apt install sysstat on Debian and Ubuntu.
Newer sysstat releases add options not present in the tested 12.7.6 build; check pidstat --help on your host before using version-specific output formats.
pidstat — column guide
CPU columns (-u, default)
| Column | Meaning |
|---|---|
%usr |
User-space CPU time for the task |
%system |
Kernel-mode CPU time for the task |
%guest |
Guest CPU time when running a virtual CPU |
%wait |
Time the task spent waiting for CPU while runnable |
%CPU |
Total CPU share for the task; can exceed 100% when a multi-threaded process uses more than one CPU in the sample window |
CPU |
Last CPU the task ran on |
Disk I/O columns (-d)
| Column | Meaning |
|---|---|
kB_rd/s / kB_wr/s |
Kibibytes read or written per second, despite the kB label |
kB_ccwr/s |
Kibibytes of cancelled writes |
iodelay |
Block I/O delay in clock ticks, including sync I/O and swap-in waits |
Memory columns (-r)
| Column | Meaning |
|---|---|
minflt/s |
Minor page faults per second (no disk read required) |
majflt/s |
Major page faults per second (page loaded from disk) |
VSZ |
Virtual memory size in kibibytes |
RSS |
Resident set size in kibibytes |
%MEM |
Share of physical memory |
Pair disk I/O columns with iostat at the device level — pidstat -d names the PID, not the block device.
pidstat — command examples
Essential Default per-process CPU snapshot
Run pidstat with no flags to list active tasks and CPU share since boot.
pidstat | head -10Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:53:18 PM UID PID %usr %system %guest %wait %CPU CPU Command
11:53:18 PM 0 1 0.03 0.06 0.00 0.08 0.08 1 systemd
11:53:18 PM 0 2 0.00 0.00 0.00 0.00 0.00 0 kthreadd
11:53:18 PM 0 11 0.00 0.03 0.00 0.03 0.03 0 kworker/0:0H-kblockdOnly tasks with non-zero counters appear unless you add -p ALL.
Essential Live CPU samples with interval and count
Pass interval and count to catch short-lived spikes during a job.
pidstat 1 2 | head -18Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:53:18 PM UID PID %usr %system %guest %wait %CPU CPU Command
11:53:19 PM 0 2314 0.93 0.00 0.00 0.93 0.93 0 node
11:53:19 PM 0 4458 72.22 82.41 0.00 0.00 154.63 1 hugo
11:53:19 PM UID PID %usr %system %guest %wait %CPU CPU Command
11:53:20 PM 389 1395 0.00 0.99 0.00 0.00 0.99 0 ns-slapd
11:53:20 PM 0 4458 74.26 109.90 0.00 0.00 184.16 1 hugo
Average: UID PID %usr %system %guest %wait %CPU CPU Command
Average: 0 4458 73.24 105.16 0.00 0.00 178.40 - hugo%CPU above 100% means the process used more than one CPU worth of time in that one-second window. Unlike vmstat and iostat, pidstat does not print a leading since-boot line when a non-zero interval is supplied.
Essential Per-process disk I/O (-d)
-d reports per-task read and write rates in KiB/s, despite displaying kB in the column names — the usual follow-up when mpstat shows high %iowait.
pidstat -d | head -9Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:53:20 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
11:53:20 PM 0 1 102.87 50.35 0.01 0 systemd
11:53:20 PM 0 590 0.00 55.06 0.00 0 jbd2/dm-3-8
11:53:20 PM 0 671 0.31 0.00 0.00 0 systemd-journalAdd an interval during a slow backup: pidstat -d 1 5.
Common Page faults and RSS (-r)
-r shows whether a process is actively faulting pages or holding a large resident footprint.
pidstat -r | head -9Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:53:20 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command
11:53:20 PM 0 1 10.69 0.08 38192 18096 0.45 systemd
11:53:20 PM 0 702 0.38 0.00 87432 40444 1.01 dmeventd
11:53:20 PM 0 725 0.25 0.00 42888 4832 0.12 systemd-udevdRising majflt/s under load often correlates with memory pressure or cold caches.
Common Filter by command name (-C and -G)
-C applies the regular expression to each reported task's command name. -G selects matching processes and becomes especially useful with -t, because all threads belonging to a matching process are then included.
pidstat -C sshd | head -7Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:53:20 PM UID PID %usr %system %guest %wait %CPU CPU Command
11:53:20 PM 0 985 0.00 0.00 0.00 0.00 0.00 1 sshd
11:53:20 PM 0 2089 0.00 0.00 0.00 0.00 0.00 0 sshd-session
11:53:20 PM 0 2110 0.04 0.28 0.00 0.87 0.33 1 sshd-sessionUse -G 'systemd' -t when you need every thread under matching processes, not only rows whose own command name matches.
Common Per-thread CPU (-t)
-t adds TGID and TID rows so you can see which thread inside a process is hot.
pidstat -t -p 1 | head -8Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:53:20 PM UID TGID TID %usr %system %guest %wait %CPU CPU Command
11:53:20 PM 0 1 - 0.03 0.06 0.00 0.08 0.08 1 systemd
11:53:20 PM 0 - 1 0.03 0.06 0.00 0.08 0.08 1 |__systemdThe |__ prefix marks individual threads under their parent TGID.
Common CPU, memory, and I/O together (-dur)
Stack activity flags to print multiple report blocks per sample.
pidstat -dur 1 2 | head -22Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:53:29 PM UID PID %usr %system %guest %wait %CPU CPU Command
11:53:30 PM 0 4458 47.22 47.22 0.00 0.00 94.44 1 hugo
11:53:29 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command
11:53:30 PM 0 4458 4.63 0.00 4181324 1754124 43.82 hugo
11:53:29 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
11:53:30 PM 0 4458 0.00 81.48 0.00 0 hugoThis layout is handy during incident triage when you need CPU, RSS, and I/O for the same PID in one pass.
Advanced Context switches (-w)
-w reports voluntary (cswch/s) and involuntary (nvcswch/s) context switches per task.
pidstat -w -p 1Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:53:20 PM UID PID cswch/s nvcswch/s Command
11:53:20 PM 0 1 1.22 0.99 systemdHigh nvcswch/s can mean CPU contention or aggressive time-slicing.
Advanced Child process CPU time (-T CHILD)
-T CHILD rolls CPU time from exited children into the parent row — useful for shell scripts and service wrappers.
pidstat -T CHILD -p 1Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:53:21 PM UID PID usr-ms system-ms guest-ms Command
11:53:21 PM 0 1 290210 267900 0 systemdValues are cumulative milliseconds for the parent plus reaped children.
Advanced Parser-friendly and human-readable output
-h places all selected activity fields for each task on one horizontal row and omits the final Average: report, which makes the output easier to parse. --human scales I/O columns.
pidstat -h 1 1 | head -4Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
# Time UID PID %usr %system %guest %wait %CPU CPU Command
11:53:24 PM 0 2110 0.00 0.96 0.00 1.92 0.96 1 sshd-sessionFor readable disk sizes: pidstat --human -d | head -8 prints values such as 102.8k instead of raw KiB values.
pidstat — when to use / when not
| Use pidstat when | Use something else when |
|---|---|
|
pidstat vs top vs iotop
| pidstat | top | iotop | |
|---|---|---|---|
| Focus | Per-PID stats over intervals | Live process list | Live per-process disk I/O |
| Thread detail | Yes (-t) |
Limited | No |
| Disk I/O per PID | Yes (-d) |
No | Yes |
| Privilege | User for visible tasks; root may be needed for all processes | User for visible tasks | Usually root |
| Best question | "How much CPU did PID X use this second?" | "What is running right now?" | "Who is writing to disk?" |
For machine-wide CPU context, pair with how to check CPU utilization in Linux.
pidstat — interview corner
What is pidstat?
pidstat is a sysstat tool that reports per-task statistics — CPU by default, plus optional memory, disk I/O, context switches, and scheduling details.
pidstat -dur 1 5A strong answer is:
"pidstat from sysstat shows per-PID CPU, memory, and I/O over sampling intervals. It answers which process is driving load when global CPU or iowait looks high."
Why can %CPU exceed 100%?
%CPU is the share of CPU time the task consumed in the sample window. A multi-threaded process using two cores fully can show roughly 200% on a two-CPU host.
A strong answer is:
"%CPU is not capped at 100 when a process uses multiple CPUs or threads in the same interval. Divide by core count or use -I on SMP if you want a normalized share."
How do pidstat intervals differ from vmstat?
Without an interval, pidstat averages since boot for each task. With pidstat 1 5, each line is a one-second live window. Unlike vmstat and iostat, pidstat does not print a leading since-boot report when a non-zero interval is supplied.
A strong answer is:
"No interval means since boot per task. With interval and count you get live windows only — no extra boot-average header like vmstat prints."
pidstat -d vs iotop?
pidstat -d reports per-PID read and write rates in KiB/s from kernel accounting — good for scripted sampling. iotop shows a live ranked list of disk consumers and usually needs root.
A strong answer is:
"pidstat -d for interval-based per-PID I/O in scripts; iotop for interactive who-is-writing-now views."
pidstat vs sar?
pidstat focuses on per-task CPU, memory, and I/O. sar covers broader system metrics — live with an interval and count, or historically from saved archives.
A strong answer is:
"pidstat for per-PID drill-down; sar for system-wide CPU, memory, disk, and network history. RHEL-family archives usually live under /var/log/sa; Debian and Ubuntu commonly use /var/log/sysstat."
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
command not found |
sysstat not installed | sudo apt install sysstat or sudo dnf install sysstat |
| Expected PID missing | Task idle in the window | Use -p ALL or add an interval: pidstat -p PID 1 5 |
-d shows no output |
No I/O in the sample | Widen the interval or run during the workload |
-C matches nothing |
Regex or command name mismatch | Try -G or -l -p PID to confirm the command field |
-T CHILD all zeros |
No reaped child time yet | Normal for long-running parents with few short children |
-R lists only kernel threads |
Realtime policy rare on user daemons | Expected — most services use SCHED_OTHER |
| Other users' tasks or I/O are missing | /proc permissions, hidepid, or capability restrictions |
Run with appropriate privileges and check /proc mount options |

