pidstat Command in Linux: Per-Process CPU, Memory, and I/O

Tested on Rocky Linux 10.2
Package sysstat 12.7.6
sysstat 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:

text
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.

bash
pidstat | head -10

Sample output:

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-kblockd

Only 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.

bash
pidstat 1 2 | head -18

Sample output:

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.

bash
pidstat -d | head -9

Sample output:

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-journal

Add 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.

bash
pidstat -r | head -9

Sample output:

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-udevd

Rising 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.

bash
pidstat -C sshd | head -7

Sample output:

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-session

Use -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.

bash
pidstat -t -p 1 | head -8

Sample output:

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  |__systemd

The |__ 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.

bash
pidstat -dur 1 2 | head -22

Sample output:

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  hugo

This 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.

bash
pidstat -w -p 1

Sample output:

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  systemd

High 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.

bash
pidstat -T CHILD -p 1

Sample output:

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  systemd

Values 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.

bash
pidstat -h 1 1 | head -4

Sample output:

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-session

For 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
  • You need which PID is using CPU, memory, or disk I/O
  • You want interval samples without a since-boot leading line
  • You need thread-level CPU (-t) or child totals (-T CHILD)
  • You are correlating process I/O with high system %iowait
  • You need per-CPU or IRQ breakdown → mpstat
  • You need device throughput and %utiliostat
  • You need live per-process disk I/O with less setup → iotop (often root)
  • You need broader historical trends → sar

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.

bash
pidstat -dur 1 5

A 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

References

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)