Mastering mpstat: A Comprehensive Guide to CPU Monitoring on Linux

In modern multi-core Linux systems, monitoring CPU utilization at a granular level is critical for identifying performance bottlenecks. Average CPU metrics often hide subtle issues—like a single core maxing out while others remain idle, which can cripple single-threaded applications. This is where mpstat (Multi-Processor Statistics) comes in: a lightweight, powerful tool part of the sysstat suite that provides per-processor and system-wide CPU utilization data.

Unlike tools like top that focus on processes, mpstat prioritizes CPU-level metrics, making it ideal for troubleshooting core-specific bottlenecks, I/O wait issues, interrupt load, and virtualized environment constraints. This guide will cover everything from installation to advanced troubleshooting, equipping you with the skills to use mpstat effectively.

Table of Contents#

  1. Installing mpstat
  2. Basic Syntax & Command Structure
  3. Core mpstat Metrics Explained
  4. Common Usage Examples
  5. Best Practices for Effective mpstat Usage
  6. Troubleshooting Scenarios with mpstat
  7. Conclusion
  8. Frequently Asked Questions
  9. References

1. Installing mpstat#

mpstat is included in the sysstat package, which is not pre-installed on all systems. Follow these steps to install it:

Linux Distributions#

  • Debian/Ubuntu:
    sudo apt update && sudo apt install sysstat -y
  • RHEL/CentOS/Fedora/Rocky/AlmaLinux:
    # For RHEL 9, CentOS Stream 9, Fedora, Rocky Linux, AlmaLinux
    sudo dnf install sysstat -y
     
    # For older RHEL/CentOS 7 systems (EOL June 2024)
    sudo yum install sysstat -y
  • Arch Linux:
    sudo pacman -S sysstat
  • OpenSUSE/SLES:
    sudo zypper install sysstat
  • Alpine Linux:
    sudo apk add sysstat
  • FreeBSD:
    sudo pkg install sysstat

Enable Historical Data Collection#

To access historical CPU statistics, follow these steps:

  1. For Debian/Ubuntu systems first: Edit /etc/default/sysstat and set ENABLED="true":

    sudo sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
  2. Enable and start the sysstat service:

    # Enable and start the service
    sudo systemctl enable --now sysstat
     
    # Verify configuration (check systemd timer)
    systemctl list-timers sysstat-collect.timer

2. Basic Syntax & Command Structure#

The core syntax for mpstat is:

mpstat [options] [interval [count]]

Where:

  • options: Modify output (e.g., per-CPU stats, interrupt data, JSON format).
  • interval: Number of seconds between consecutive samples.
  • count: Number of samples to collect (if omitted, mpstat runs indefinitely until interrupted with Ctrl+C).

Default Behavior: If no options are provided, mpstat displays average CPU utilization for all cores since system boot.

Quick Reference: Common Options#

OptionDescription
-P {cpu_list | ALL}Report stats for specific CPU(s) or all CPUs
-I {CPU | SCPU | SUM | ALL}Report interrupt statistics
-ADisplay all stats (equivalent to -u -I ALL -P ALL -n -N ALL)
-o JSONOutput in JSON format for scripting
-uReport CPU utilization (default)
-TDisplay topology elements (CORE, SOCK, NODE)
-HDetect and display hotplugged vCPUs
-N {node_list | ALL}Report stats for specific NUMA node(s)
-nReport CPU stats based on NUMA node placement
--dec={0 | 1 | 2}Set decimal precision (0–2, default 2)
-UDisplay UTC timestamp in epoch seconds
-VPrint mpstat version and exit

Environment Variables#

VariableDescription
S_COLORSControl colored output: never, always, or auto (default)
S_COLORS_SGRCustomize colors using SGR codes (e.g., I=32;22:N=34;1:W=35;1:X=31;1:Z=34;22)
S_TIME_FORMATSet to ISO for ISO 8601 date format (YYYY-MM-DD) in headers

3. Core mpstat Metrics Explained#

A typical mpstat output (from mpstat -P ALL 1 1) looks like this:

Linux 6.8.0-45-generic (ubuntu-server) 	06/08/2026 	_x86_64_	(4 CPU)

14:30:02  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
14:30:04  all     7.50    0.00     1.25     0.00    0.00    0.00    0.00    0.00    0.00    91.25
14:30:04    0    25.00    0.00     5.00     0.00    0.00    0.00    0.00    0.00    0.00    70.00
14:30:04    1     5.00    0.00     0.00     0.00    0.00    0.00    0.00    0.00    0.00    95.00
14:30:04    2     0.00    0.00     0.00     0.00    0.00    0.00    0.00    0.00    0.00   100.00
14:30:04    3     0.00    0.00     0.00     0.00    0.00    0.00    0.00    0.00    0.00   100.00

Here’s a breakdown of each metric:

ColumnDescription
CPUProcessor ID (all = average across all cores)
%usrPercentage of CPU used by user-space applications (e.g., web servers, databases)
%nicePercentage of CPU used by processes with a positive nice priority
%sysPercentage of CPU used by kernel-space operations (e.g., system calls, process scheduling)
%iowaitPercentage of CPU idle while waiting for I/O operations to complete
%irqPercentage of CPU used to handle hardware interrupts (e.g., network card, disk)
%softPercentage of CPU used to handle software interrupts (e.g., deferred hardware interrupts)
%stealPercentage of CPU time stolen by the hypervisor (relevant for virtual machines)
%guestPercentage of CPU used by guest virtual machines
%gnicePercentage of CPU used by guest virtual machines with a positive nice priority
%idlePercentage of CPU time idle (no active processes or I/O waits)

4. Common Usage Examples#

Example 1: Default System-Wide Average#

Show average CPU utilization since system boot for all cores:

mpstat

Example 2: Per-Core Real-Time Monitoring#

Sample CPU stats every 2 seconds, 5 times, for all cores (including average):

mpstat -P ALL 2 5

Example 3: Monitor a Specific CPU#

Track only CPU 1 with 1-second intervals:

mpstat -P 1 1

Example 4: View Interrupt Statistics#

Show total interrupts per CPU (useful for troubleshooting high %irq):

mpstat -P ALL -I SUM 1

Show interrupts per type (e.g., network receive, disk) per CPU:

mpstat -P ALL -I SCPU 2

Example 5: Historical CPU Data#

Access historical data collected by sysstat (replace sa15 with the day of the month):

# View historical per-CPU statistics
sar -P ALL -f /var/log/sa/sa15

Note for Debian/Ubuntu users: The log path is /var/log/sysstat/ instead of /var/log/sa/.

Example 6: Machine-Readable JSON Output#

Generate JSON output for script parsing (use jq to filter results):

mpstat -o JSON 1 2 | jq '.sysstat.hosts[0].statistics[0]."cpu-load"[] | {cpu: .cpu, usr: .user, idle: .idle}'

Example 7: Combine with Other Tools#

Pipe mpstat output to awk to alert on high CPU usage:

mpstat 1 10 | awk '$12 ~ /^[0-9.]/ && $12 < 10 {print "WARNING: Low idle CPU: " $12 "%"}'

Example 8: Comprehensive Output with -A#

The -A flag displays all CPU utilization and interrupt statistics in a single report:

mpstat -A

Example 9: NUMA Node Statistics#

Monitor CPU utilization grouped by NUMA node:

mpstat -N ALL 2 5

Example 10: Topology Information#

Display core, socket, and NUMA node mappings alongside CPU stats:

mpstat -T -P ALL 1 3

Example 11: Custom Decimal Precision#

Display CPU stats with no decimal places for a cleaner real-time view:

mpstat --dec=0 -P ALL 1 5

5. Best Practices for Effective mpstat Usage#

  1. Prioritize Per-Core Stats: Always use -P ALL to avoid hiding single-core bottlenecks. Average stats can mask a core running at 100% while others are idle.
  2. Use Interval Sampling: Avoid relying solely on the default "since boot" average. Use interval and count to capture real-time behavior during performance issues.
  3. Correlate with Other Tools: Combine mpstat with:
    • iostat: To diagnose high %iowait (disk I/O issues).
    • pidstat: To identify processes causing high %usr or %sys load.
    • top/htop: To monitor process-level CPU usage.
  4. Save Output for Later Analysis: For long-running monitoring, redirect output to a file:
    mpstat -P ALL 60 1440 > cpu_monitor_24h.log
  5. Leverage JSON for Automation: Use -o JSON to integrate mpstat into custom monitoring scripts or dashboards.
  6. Understand %iowait Context: High %iowait doesn’t always mean the CPU is bottlenecked—it means processes are waiting for I/O. Use iostat to confirm disk saturation.
  7. Enable Historical Data: Configure sysstat to collect regular samples for trend analysis (e.g., comparing CPU usage during peak and off-peak hours).

6. Troubleshooting Scenarios with mpstat#

Scenario 1: Single-Core Bottleneck#

Symptom: mpstat -P ALL shows one core at 100% %usr, others idle.
Root Cause: A single-threaded application is monopolizing one core.
Fix:

  1. Identify the process with top -H (show threads) or pidstat -u -p <PID>.
  2. Optimize the application to use multi-threading, or scale horizontally (run multiple instances across cores).

Scenario 2: High %iowait#

Symptom: mpstat shows %iowait > 20% for extended periods.
Fix:

  1. Use iostat -x 2 to identify which disk is saturated (look for %util > 90%).
  2. Use pidstat -d 2 to find processes generating heavy I/O.
  3. Reschedule I/O-heavy tasks (e.g., backups) to off-peak hours, or upgrade to faster storage.

Scenario 3: High %steal in Virtual Machines#

Symptom: mpstat shows %steal > 10% consistently.
Root Cause: The hypervisor is overcommitted and stealing CPU time for other VMs.
Fix:

  1. Contact your cloud provider to check host resource utilization.
  2. Reduce VM CPU allocation or migrate to a less crowded host.

Scenario 4: High %soft (Software Interrupts)#

Symptom: mpstat shows %soft > 15%.
Fix:

  1. Use mpstat -I SCPU 1 to identify the interrupt type (e.g., NET_RX for network receive).
  2. Enable Receive Side Scaling (RSS) on network cards to distribute interrupts across cores:
      sudo ethtool -K eth0 rx-hashing on

7. Conclusion#

mpstat is an indispensable tool for Linux system administrators and DevOps engineers. Its ability to provide per-core CPU metrics fills a critical gap in performance monitoring, allowing you to identify bottlenecks that average-based tools miss. By combining mpstat with complementary tools like iostat and pidstat, you can diagnose and resolve complex performance issues quickly.

Whether you're troubleshooting a slow application, optimizing a virtualized environment, or monitoring CPU trends over time, mpstat should be a core part of your toolkit.


8. Frequently Asked Questions#

What is the difference between mpstat and top?#

top shows process-level CPU usage in real time, while mpstat focuses on CPU-level metrics per core. Use top to find which process is consuming CPU, and mpstat to identify which core is saturated and whether interrupts, I/O wait, or steal time are contributing.

How do I check my mpstat version?#

Run mpstat -V to display the installed sysstat version. The latest release is sysstat 12.7.9 (December 2025).

What does high %iowait mean in mpstat?#

High %iowait means CPUs are idle while waiting for disk or I/O operations to complete. It does not mean the CPU is bottlenecked—it indicates an I/O bottleneck. Use iostat -x 2 to confirm which disk is saturated.

Can I use mpstat on virtual machines?#

Yes. In VMs, pay attention to the %steal column, which shows CPU time taken by the hypervisor. Consistently high %steal (>10%) indicates the host is overcommitted.

How do I save mpstat output to a file?#

Redirect output to a file:

mpstat -P ALL 60 1440 > cpu_monitor_24h.log

Or use JSON format for easier parsing:

mpstat -o JSON 1 5 > cpu_stats.json

How do I disable colored output from mpstat?#

Set the S_COLORS environment variable:

S_COLORS=never mpstat -P ALL 1 5

9. References#

  1. sysstat Official Documentation: github.com/sysstat/sysstat
  2. mpstat Man Page (man7.org): man7.org/linux/man-pages/man1/mpstat.1.html
  3. mpstat Man Page: man mpstat
  4. sysstat CHANGES (version history): github.com/sysstat/sysstat/blob/master/CHANGES
  5. Red Hat Performance Tuning Guide: access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/monitoring_and_managing_system_status_and_performance/
  6. Linux Kernel Interrupts Guide: kernel.org/doc/html/latest/core-api/genericirq.html
  7. sysstat FAQ and Configuration: sysstat.github.io/faq.html