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#
- Installing mpstat
- Basic Syntax & Command Structure
- Core mpstat Metrics Explained
- Common Usage Examples
- Best Practices for Effective mpstat Usage
- Troubleshooting Scenarios with mpstat
- Conclusion
- Frequently Asked Questions
- 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:
-
For Debian/Ubuntu systems first: Edit
/etc/default/sysstatand setENABLED="true":sudo sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat -
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,
mpstatruns indefinitely until interrupted withCtrl+C).
Default Behavior: If no options are provided, mpstat displays average CPU utilization for all cores since system boot.
Quick Reference: Common Options#
| Option | Description |
|---|---|
-P {cpu_list | ALL} | Report stats for specific CPU(s) or all CPUs |
-I {CPU | SCPU | SUM | ALL} | Report interrupt statistics |
-A | Display all stats (equivalent to -u -I ALL -P ALL -n -N ALL) |
-o JSON | Output in JSON format for scripting |
-u | Report CPU utilization (default) |
-T | Display topology elements (CORE, SOCK, NODE) |
-H | Detect and display hotplugged vCPUs |
-N {node_list | ALL} | Report stats for specific NUMA node(s) |
-n | Report CPU stats based on NUMA node placement |
--dec={0 | 1 | 2} | Set decimal precision (0–2, default 2) |
-U | Display UTC timestamp in epoch seconds |
-V | Print mpstat version and exit |
Environment Variables#
| Variable | Description |
|---|---|
S_COLORS | Control colored output: never, always, or auto (default) |
S_COLORS_SGR | Customize colors using SGR codes (e.g., I=32;22:N=34;1:W=35;1:X=31;1:Z=34;22) |
S_TIME_FORMAT | Set 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:
| Column | Description |
|---|---|
CPU | Processor ID (all = average across all cores) |
%usr | Percentage of CPU used by user-space applications (e.g., web servers, databases) |
%nice | Percentage of CPU used by processes with a positive nice priority |
%sys | Percentage of CPU used by kernel-space operations (e.g., system calls, process scheduling) |
%iowait | Percentage of CPU idle while waiting for I/O operations to complete |
%irq | Percentage of CPU used to handle hardware interrupts (e.g., network card, disk) |
%soft | Percentage of CPU used to handle software interrupts (e.g., deferred hardware interrupts) |
%steal | Percentage of CPU time stolen by the hypervisor (relevant for virtual machines) |
%guest | Percentage of CPU used by guest virtual machines |
%gnice | Percentage of CPU used by guest virtual machines with a positive nice priority |
%idle | Percentage 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:
mpstatExample 2: Per-Core Real-Time Monitoring#
Sample CPU stats every 2 seconds, 5 times, for all cores (including average):
mpstat -P ALL 2 5Example 3: Monitor a Specific CPU#
Track only CPU 1 with 1-second intervals:
mpstat -P 1 1Example 4: View Interrupt Statistics#
Show total interrupts per CPU (useful for troubleshooting high %irq):
mpstat -P ALL -I SUM 1Show interrupts per type (e.g., network receive, disk) per CPU:
mpstat -P ALL -I SCPU 2Example 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/sa15Note 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 -AExample 9: NUMA Node Statistics#
Monitor CPU utilization grouped by NUMA node:
mpstat -N ALL 2 5Example 10: Topology Information#
Display core, socket, and NUMA node mappings alongside CPU stats:
mpstat -T -P ALL 1 3Example 11: Custom Decimal Precision#
Display CPU stats with no decimal places for a cleaner real-time view:
mpstat --dec=0 -P ALL 1 55. Best Practices for Effective mpstat Usage#
- Prioritize Per-Core Stats: Always use
-P ALLto avoid hiding single-core bottlenecks. Average stats can mask a core running at 100% while others are idle. - Use Interval Sampling: Avoid relying solely on the default "since boot" average. Use
intervalandcountto capture real-time behavior during performance issues. - Correlate with Other Tools: Combine
mpstatwith:iostat: To diagnose high%iowait(disk I/O issues).pidstat: To identify processes causing high%usror%sysload.top/htop: To monitor process-level CPU usage.
- Save Output for Later Analysis: For long-running monitoring, redirect output to a file:
mpstat -P ALL 60 1440 > cpu_monitor_24h.log - Leverage JSON for Automation: Use
-o JSONto integratempstatinto custom monitoring scripts or dashboards. - Understand
%iowaitContext: High%iowaitdoesn’t always mean the CPU is bottlenecked—it means processes are waiting for I/O. Useiostatto confirm disk saturation. - Enable Historical Data: Configure
sysstatto 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:
- Identify the process with
top -H(show threads) orpidstat -u -p <PID>. - 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:
- Use
iostat -x 2to identify which disk is saturated (look for%util> 90%). - Use
pidstat -d 2to find processes generating heavy I/O. - 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:
- Contact your cloud provider to check host resource utilization.
- Reduce VM CPU allocation or migrate to a less crowded host.
Scenario 4: High %soft (Software Interrupts)#
Symptom: mpstat shows %soft > 15%.
Fix:
- Use
mpstat -I SCPU 1to identify the interrupt type (e.g.,NET_RXfor network receive). - 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.logOr use JSON format for easier parsing:
mpstat -o JSON 1 5 > cpu_stats.jsonHow do I disable colored output from mpstat?#
Set the S_COLORS environment variable:
S_COLORS=never mpstat -P ALL 1 59. References#
- sysstat Official Documentation: github.com/sysstat/sysstat
- mpstat Man Page (man7.org): man7.org/linux/man-pages/man1/mpstat.1.html
- mpstat Man Page:
man mpstat - sysstat CHANGES (version history): github.com/sysstat/sysstat/blob/master/CHANGES
- Red Hat Performance Tuning Guide: access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/monitoring_and_managing_system_status_and_performance/
- Linux Kernel Interrupts Guide: kernel.org/doc/html/latest/core-api/genericirq.html
- sysstat FAQ and Configuration: sysstat.github.io/faq.html