How to Check CPU Usage in Linux

By 

Published on

8 min read

Checking CPU usage in Linux with terminal monitoring tools

A Linux server tells you what its CPUs are doing through several built-in tools, each with a different angle. top and htop show the live picture. mpstat, vmstat, and sar from the sysstat package report numeric samples that suit scripts and dashboards. ps attributes usage to specific processes, and uptime summarizes the load over the last fifteen minutes.

This guide explains how to read CPU usage from each of those tools, which one to reach for in which situation, and how to interpret common output fields.

Quick Reference

ToolBest forCommand
topLive snapshot, sort by CPUtop
htopInteractive, per-core viewhtop
mpstatPer-core sampling for scriptsmpstat -P ALL 1 5
vmstatSystem-wide CPU and memoryvmstat -y 1 5
sarCurrent or saved CPU samplessar -u 1 5
psPer-process attributionps -eo pid,user,%cpu,comm --sort=-%cpu | head
uptimeLoad average summaryuptime
nprocLogical core countnproc
lscpuCPU topology detailslscpu

Method 1: top

The top command is available on most Linux systems without any extra packages. Run it without arguments to open the live view:

Terminal
top

The header summarizes the CPU lines:

output
%Cpu(s):  4.2 us,  1.3 sy,  0.0 ni, 93.8 id,  0.5 wa,  0.0 hi,  0.2 si,  0.0 st

The fields tell you where CPU time goes. us is user-space code, sy is kernel code, id is idle, wa is time waiting for I/O, and st is time stolen by the hypervisor on a virtual machine. A high wa value points at slow disks rather than a CPU bottleneck.

Press 1 while top is open to switch from the aggregate line to one row per logical CPU. Press P to sort processes by CPU usage, M to sort by memory, and q to quit.

Method 2: htop

htop is an interactive replacement for top. It is available in the default repositories of most Linux distributions, but it may not be installed by default.

On Ubuntu, Debian, and Derivatives:

Terminal
sudo apt install htop

On Fedora, RHEL, and Derivatives:

Terminal
sudo dnf install htop

Run it the same way:

Terminal
htop

htop shows a colored bar per CPU at the top, a memory and swap bar, and a sortable process table below. Click a column header or use the function keys to sort. Search for a process with F3, filter with F4, and send a signal to a selected process with F9.

Method 3: mpstat

mpstat is part of the sysstat package and is the right tool when you need numeric CPU samples per core. Install it once before using mpstat or sar.

On Ubuntu, Debian, and Derivatives:

Terminal
sudo apt install sysstat

On Fedora, RHEL, and Derivatives:

Terminal
sudo dnf install sysstat

Sample all cores at one-second intervals five times:

Terminal
mpstat -P ALL 1 5
output
03:14:00 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
03:14:01 PM  all    3.27    0.00    0.75    0.00    0.00    0.00    0.00    0.00    0.00   95.98
03:14:01 PM    0    4.95    0.00    0.99    0.00    0.00    0.00    0.00    0.00    0.00   94.06
03:14:01 PM    1    1.00    0.00    1.00    0.00    0.00    0.00    0.00    0.00    0.00   98.00

The all row is the aggregate. Each numbered row is a single logical CPU. Use this output when one core is pinned at 100 percent and the others are idle, which can happen when an application is single-threaded.

Method 4: vmstat

vmstat is part of procps and combines CPU usage with memory, swap, and I/O. The first report normally shows averages since boot, so use -y when you want only interval samples. The columns at the right are the CPU summary:

Terminal
vmstat -y 1 5
output
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 7430080 311288 1843264    0    0     8    18  148  263  3  1 96  0  0
 0  0      0 7430080 311288 1843264    0    0     0     0  127  226  1  0 99  0  0

r is the run queue length, which is how many processes are ready to use a CPU. A run queue consistently larger than the number of CPUs is a sign of CPU pressure. The cpu columns mirror the meaning of the top header.

Method 5: sar

sar, also from sysstat, can print current samples and read saved activity logs. On Ubuntu and Debian, enable history collection after installing sysstat:

Terminal
sudo sed -i 's/^ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
sudo systemctl enable --now sysstat

The collector setup differs between distributions. If sar shows no saved history, check your distribution’s sysstat service or timer configuration.

Show current CPU samples:

Terminal
sar -u 1 5
output
03:15:01 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
03:15:02 PM     all      2.34      0.00      0.71      0.05      0.00     96.90
03:15:03 PM     all      2.18      0.00      0.69      0.04      0.00     97.09

Each row is a sample interval. Combine with -f to read an older log, for example sar -u -f /var/log/sysstat/sa10 for the tenth of the month on systems that store logs in /var/log/sysstat/. This is the right tool when you need to confirm that a slowdown reported yesterday lined up with a CPU spike.

Method 6: ps

The ps command lists every process and lets you sort by CPU percentage. The pattern most admins reach for is:

Terminal
ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | head
output
    PID USER     %CPU %MEM COMMAND
   1437 dejan    23.5  4.2 firefox
   2049 dejan    11.2  2.8 node
   1102 root      4.7  0.9 systemd-journal

The output is a snapshot at the moment ps ran. The %CPU value is the average CPU usage over the lifetime of the process, not an instantaneous reading. For a live view, repeat the command with watch:

Terminal
watch -n 2 'ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | head'

watch reruns the command every two seconds, which gives you a refreshing top-five view without leaving the shell.

Method 7: uptime and Load Averages

The uptime command is the smallest of the lot. Without arguments it prints the system uptime and the load average:

Terminal
uptime
output
 15:04:23 up  3:17,  2 users,  load average: 0.42, 0.35, 0.31

The three numbers are the average number of processes that are runnable or in uninterruptible sleep over the last 1, 5, and 15 minutes. Compare them with nproc:

Terminal
nproc
output
8

A load average that stays below the core count is healthy. A load average well above the core count means processes are queueing for CPU time. The 15-minute value is the trend; the 1-minute value reacts to short spikes.

Method 8: Capacity Context

Before you read CPU usage, know what the host has. lscpu summarizes the CPU model, sockets, cores, and threads. For a deeper hardware view, see the guide on checking CPU information in Linux .

Terminal
lscpu
output
Architecture:            x86_64
CPU op-mode(s):          32-bit, 64-bit
Address sizes:           46 bits physical, 48 bits virtual
Byte Order:              Little Endian
CPU(s):                  8
On-line CPU(s) list:     0-7
Vendor ID:               GenuineIntel
Model name:              Intel(R) Core(TM) i7-9700K CPU @ 3.60 GHz
Thread(s) per core:      1
Core(s) per socket:      8
Socket(s):               1

Thread(s) per core: 1 means hyper-threading is disabled or not present, so each logical CPU is a physical core. A high CPU usage on a chip with eight physical cores is different from the same number on a four-core chip with hyper-threading.

Troubleshooting

mpstat: command not found
The sysstat package is not installed. Install it with sudo apt install sysstat on Ubuntu, Debian, and Derivatives, or sudo dnf install sysstat on Fedora, RHEL, and Derivatives.

sar reports Cannot open /var/log/sysstat/
Sample collection is not enabled. Set ENABLED="true" in /etc/default/sysstat and restart the service with sudo systemctl restart sysstat. Wait at least one collection interval before rerunning sar.

top shows more than 100% CPU for one process
The default mode shows percentage relative to a single CPU, so a multi-threaded process can exceed 100 percent. Press Shift+I to toggle Irix mode off, and the value normalizes across all CPUs.

Load average looks high but no process consumes CPU
Load includes processes in D state, which is uninterruptible sleep. Check ps -eo state,pid,comm | awk '$1 ~ /D/' to find processes blocked on I/O. The cause is usually a slow or stalled disk.

Per-core view in htop is empty
Old terminal sizes hide the CPU bar. Resize the window or set Display options inside htop with F2.

FAQ

Which tool should I check first?
Run top or htop for a live picture, then drop to mpstat and sar when you need numbers or history. ps answers the per-process question once you know there is a problem.

What does %steal mean?
%steal is the time the hypervisor took from the guest VM to run something else. A consistent non-zero %steal value on a VM means the host is over-committed and the guest cannot get the CPU it asked for.

How do I count CPUs from a script?
Use nproc for the logical CPU count, or nproc --all to include offline CPUs. Both return a single integer and are stable across distributions.

Is high CPU always bad?
No. A batch job that finishes faster on a CPU running at full capacity is healthier than the same job spread thinly over a long period. CPU is bad when the load average exceeds the core count for sustained periods or when interactive workloads time out.

Conclusion

Pick the tool that matches the question. top and htop answer “what is happening right now”. mpstat and vmstat answer “is the load even across cores”. sar answers “what happened last night”. Treat load averages as a trend, not a verdict, and always read CPU numbers in the context of the core count from nproc.

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page