mpstat is part of the sysstat toolkit. It prints CPU utilization per logical processor, optional NUMA node breakdowns, and interrupt statistics from /proc/stat, /proc/interrupts, and /proc/softirqs. On a busy host, one overloaded CPU while others sit idle often shows up here before it is obvious in a single global average.
Tested on: Rocky Linux 10.2; sysstat 12.7.6; kernel 6.12.0-211.28.1.el10_2.x86_64.
mpstat — quick reference
Default CPU report and intervals
| When to use | Command |
|---|---|
| Global CPU utilization since boot | mpstat |
| Sample every N seconds until Ctrl+C | mpstat N |
| N samples at M-second intervals | mpstat M N |
| Show sysstat version | mpstat -V |
Per-processor and NUMA views
| When to use | Command |
|---|---|
One row per CPU plus global all average |
mpstat -P ALL |
| Single CPU only (CPU 0 is first) | mpstat -P 0 |
| Several CPUs by list or range | mpstat -P 0,1 or mpstat -P 0-3 |
| CPU utilization by NUMA node | mpstat -n |
| Stats for one NUMA node | mpstat -N 0 |
| All NUMA nodes | mpstat -N ALL |
| Show CORE, SOCK, NODE topology columns | mpstat -P ALL -T |
Interrupt statistics (-I)
| When to use | Command |
|---|---|
| Total interrupts per second (summary) | mpstat -I SUM |
Per hardware IRQ from /proc/interrupts |
mpstat -I CPU |
Per software IRQ from /proc/softirqs |
mpstat -I SCPU |
| Hardware + software + summary | mpstat -I ALL |
Combined and output format
| When to use | Command |
|---|---|
| CPU, NUMA, and all interrupt reports | mpstat -A |
| CPU report only (same as default) | mpstat -u |
| Hotplugged vCPU detection | mpstat -H |
| Integer percentages (no decimals) | mpstat --dec=0 |
| One decimal place | mpstat --dec=1 |
| JSON for scripts and dashboards | mpstat -o JSON |
| JSON with per-CPU rows | mpstat -P ALL -o JSON |
mpstat — command syntax
Synopsis from sysstat 12.7.6:
mpstat [ -A ] [ --dec={ 0 | 1 | 2 } ] [ -H ] [ -n ] [ -u ] [ -T ] [ -V ]
[ -I { SUM | CPU | SCPU | ALL } ] [ -N { node_list | ALL } ]
[ -o JSON ] [ -P { cpu_list | ALL } ] [ interval [ count ] ]With no activity flag selected, mpstat prints the CPU utilization report (-u). The first sample without an interval averages since boot; pass interval and count for live windows. Install the package with sudo dnf install sysstat on RHEL-family hosts or sudo apt install sysstat on Debian and Ubuntu.
mpstat — column guide
| Column | Meaning |
|---|---|
%usr |
Time running user-space code (normal priority) |
%nice |
Time running niced user processes |
%sys |
Time in kernel mode (syscalls, not including interrupts) |
%iowait |
Time the CPU was idle while the system had an outstanding disk-I/O request. Treat it as an approximate signal, especially per CPU on multicore systems. |
%irq |
Time servicing hardware interrupts |
%soft |
Time servicing softirqs |
%steal |
Time stolen by the hypervisor (VMs) |
%guest / %gnice |
Guest CPU time (virtualized workloads) |
%idle |
Truly idle time |
All displayed utilization fields—%usr, %nice, %sys, %iowait, %irq, %soft, %steal, %guest, %gnice, and %idle—should total approximately 100%, allowing for rounding. mpstat subtracts guest time from its displayed %usr and %nice values before reporting %guest and %gnice separately, so the displayed columns can be added without double-counting guest time. A single CPU at high %sys or %irq while all looks fine is a common sign of uneven load or IRQ affinity issues.
mpstat — command examples
Essential Default global CPU snapshot
Run mpstat with no flags when you want one global CPU line since boot.
mpstatSample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:39:57 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:39:57 PM all 3.71 0.00 8.94 0.96 9.81 1.40 0.00 0.00 0.00 75.17The all row averages every logical CPU. High %irq here means interrupt handling is a noticeable slice of CPU time across the box.
Essential Live samples with interval and count
Pass interval and count to watch CPU during a job or deployment window.
mpstat 1 2Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:39:57 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:39:58 PM all 0.00 0.00 1.00 0.00 1.50 0.00 0.00 0.00 0.00 97.50
11:39:59 PM all 0.51 0.00 0.00 0.00 2.02 0.51 0.00 0.00 0.00 96.97
Average: all 0.25 0.00 0.50 0.00 1.76 0.25 0.00 0.00 0.00 97.24Each numbered line covers one second; Average: is the mean across the interval samples, not since boot.
Essential Per-CPU breakdown (-P ALL)
Use -P ALL when you suspect one core is hot while the global average hides it.
mpstat -P ALLSample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:39:59 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:39:59 PM all 3.71 0.00 8.94 0.96 9.81 1.40 0.00 0.00 0.00 75.18
11:39:59 PM 0 4.73 0.00 5.33 0.58 12.64 1.24 0.00 0.00 0.00 75.49
11:39:59 PM 1 2.60 0.00 12.87 1.38 6.74 1.57 0.00 0.00 0.00 74.84CPU 1 shows higher %sys than CPU 0 in this snapshot — worth correlating with process affinity or IRQ placement.
Common One processor only (-P 0)
Filter to a single CPU when you already know which core to watch.
mpstat -P 0Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:39:59 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:39:59 PM 0 4.73 0.00 5.33 0.58 12.64 1.24 0.00 0.00 0.00 75.49Combine with an interval during a pinned workload: mpstat -P 0 1 5.
Common NUMA node CPU stats (-n and -N)
On NUMA hardware, -n rolls up utilization by memory node; -N limits output to specific nodes.
mpstat -N ALLSample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:40:21 PM NODE %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:40:21 PM all 3.70 0.00 8.92 0.96 9.79 1.40 0.00 0.00 0.00 75.22
11:40:21 PM 0 3.70 0.00 8.92 0.96 9.79 1.40 0.00 0.00 0.00 75.22This lab VM has one NUMA node, so all and 0 match. On multi-socket servers, compare nodes to identify uneven CPU utilization across NUMA nodes. Use numastat or hardware performance counters when you need to investigate local-versus-remote memory access.
Common Interrupt rate summary (-I SUM)
-I SUM prints total interrupts per second — a quick IRQ health check before diving into per-vector detail.
mpstat -I SUMSample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:40:01 PM CPU intr/s
11:40:01 PM all 1139.89Pair with -P ALL when IRQ load is uneven across CPUs: mpstat -I SUM -P ALL 1 3.
Common Hardware and software IRQs (-I CPU and -I SCPU)
-I CPU lists each hardware IRQ from /proc/interrupts; -I SCPU lists softirq types from /proc/softirqs.
mpstat -I SCPU | head -6Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:40:21 PM CPU HI/s TIMER/s NET_TX/s NET_RX/s BLOCK/s IRQ_POLL/s TASKLET/s SCHED/s HRTIMER/s RCU/s
11:40:21 PM 0 0.00 36.65 0.00 7.22 50.44 0.00 0.01 45.09 0.00 97.55
11:40:21 PM 1 0.00 49.70 0.00 19.16 108.58 0.00 0.13 45.17 0.00 83.36High BLOCK/s or NET_RX/s often tracks storage or network driver activity on that CPU.
Advanced Full report bundle (-A)
-A is shorthand for -n -u -I ALL and implies -N ALL -P ALL unless you override them on the command line.
mpstat -A | head -20Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:40:01 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:40:01 PM all 3.71 0.00 8.94 0.96 9.81 1.40 0.00 0.00 0.00 75.18
11:40:01 PM 0 4.73 0.00 5.33 0.58 12.64 1.24 0.00 0.00 0.00 75.49
11:40:01 PM 1 2.60 0.00 12.87 1.38 6.73 1.57 0.00 0.00 0.00 74.85
11:40:01 PM NODE %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:40:01 PM all 3.71 0.00 8.94 0.96 9.81 1.40 0.00 0.00 0.00 75.18
11:40:01 PM 0 3.71 0.00 8.94 0.96 9.81 1.40 0.00 0.00 0.00 75.18
11:40:01 PM CPU intr/s
11:40:01 PM all 1139.90Use this during deep triage; for daily checks, mpstat -P ALL 1 5 is usually enough.
Advanced CPU topology columns (-P ALL -T)
-T adds CORE, SOCK, and NODE identifiers when the kernel exposes them. Pair it with -P ALL so each logical CPU gets its own row with topology values.
mpstat -P ALL -TSample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:46:47 PM CPU CORE SOCK NODE %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:46:47 PM all 3.73 0.00 8.89 0.98 9.77 1.39 0.00 0.00 0.00 75.24
11:46:47 PM 0 0 0 0 4.75 0.00 5.28 0.58 12.56 1.23 0.00 0.00 0.00 75.60
11:46:47 PM 1 1 0 0 2.61 0.00 12.84 1.41 6.72 1.57 0.00 0.00 0.00 74.84The global all row has no single topology assignment, so its topology fields remain blank. The individual CPU rows selected by -P ALL show the logical core, socket, and NUMA node reported by the kernel.
Advanced Rounding and JSON export (--dec and -o JSON)
--dec controls decimal places; -o JSON feeds monitoring pipelines.
mpstat --dec=0Sample output:
Linux 6.12.0-211.28.1.el10_2.x86_64 (ldap1.example.com) 07/18/2026 _x86_64_ (2 CPU)
11:40:01 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:40:01 PM all 4 0 9 1 10 1 0 0 0 75For JSON:
mpstat -o JSON | head -15Sample output:
{"sysstat": {
"hosts": [
{
"nodename": "ldap1.example.com",
"sysname": "Linux",
"release": "6.12.0-211.28.1.el10_2.x86_64",
"machine": "x86_64",
"number-of-cpus": 2,
"date": "07/18/2026",
"statistics": [
{
"timestamp": "11:40:01 PM",
"cpu-load": [
{"cpu": "all", "usr": 3.71, "nice": 0.00, "sys": 8.94, "iowait": 0.96, "irq": 9.81, "soft": 1.40, "steal": 0.00, "guest": 0.00, "gnice": 0.00, "idle": 75.18}Pipe through jq to extract one field in automation.
mpstat — when to use / when not
| Use mpstat when | Use something else when |
|---|---|
|
mpstat vs top vs vmstat
| mpstat | top | vmstat | |
|---|---|---|---|
| Focus | Per-CPU and IRQ stats | Live process list | Memory, I/O, run queue |
| Per-CPU rows | Yes (-P ALL) |
Per-CPU summary line | Single CPU column set |
| Interrupt detail | Yes (-I) |
No | No |
| Best question | "Is one CPU or IRQ vector hot?" | "Which PID is burning CPU?" | "Is the box swapping or I/O bound?" |
For a broader CPU troubleshooting walkthrough, see how to check CPU utilization in Linux.
Related commands
| Command | One line |
|---|---|
| iostat | Disk and global CPU I/O wait |
| vmstat | Memory, swap, and system-wide CPU |
| sar | Historical sysstat archives |
| pidstat | Per-process CPU and I/O |
Browse the full index in our Linux commands reference.
mpstat — interview corner
What is mpstat?
mpstat is a sysstat tool that reports processor-related statistics: CPU utilization per logical CPU, optional NUMA placement, and interrupt rates.
mpstat -P ALL 1 3A strong answer is:
"mpstat from sysstat shows per-CPU utilization and interrupt stats. -P ALL breaks out each core; interval sampling gives live averages instead of since-boot numbers."
What do %iowait, %irq, and %soft mean?
%iowait is idle CPU time while the system had an outstanding disk-I/O request — an approximate signal, not a direct storage bottleneck indicator. %irq is hardware interrupt handling; %soft is softirq processing (network stack, block layer, timers).
A strong answer is:
"High iowait can support an I/O-wait hypothesis, but it does not identify the device or prove that storage is the bottleneck. Correlate it with iostat, pidstat -d, application latency, and I/O pressure. High irq or soft on one CPU often means interrupt affinity or driver load on that core."
Why does the first mpstat line differ from interval samples?
Without an interval, mpstat averages since boot. With mpstat 1 5, each sample line covers one second and Average: summarizes only those samples.
A strong answer is:
"With no interval, mpstat reports averages since boot. Adding an interval and count makes it report live sampling windows. Unlike vmstat and iostat, mpstat does not print a leading since-boot report when a non-zero interval is supplied."
mpstat vs top for CPU troubleshooting?
top shows which processes consume CPU. mpstat shows how each CPU spends time, including interrupt columns top does not break out per core.
A strong answer is:
"top for the process list; mpstat -P ALL when global CPU looks fine but you suspect one hot core or IRQ load."
mpstat vs sar?
mpstat specializes in current per-CPU, NUMA, and interrupt statistics. sar can report live system activity using an interval and count or read previously saved sysstat archives.
A strong answer is:
"Use mpstat for focused live per-CPU and interrupt analysis. Use sar for broader system statistics, either live with an interval and count or historically from saved archives. RHEL-family systems normally use /var/log/sa, while 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 |
Only all row on UP machine |
Uniprocessor host | Expected — per-CPU rows need multiple logical CPUs |
-I SCPU missing or empty |
Kernel older than 2.6.31 | Upgrade kernel or use -I SUM / -I CPU only |
-N shows one node |
Single-node hardware or VM | Normal on laptops and small VMs; use -P ALL instead |
-H looks like default output |
No hotplugged vCPUs present | -H adds value only when vCPUs are hot-added |
High %steal on a VM |
Host oversubscription | Move workload or resize the guest; check hypervisor capacity |
