When a critical application on a server with 64GB of RAM starts swapping to disk, the CPU spikes to 100%, and users flood the helpdesk, you need to know exactly where to look. The problem is almost never where you think it is. I once spent hours staring at the top command on a virtualized cluster for a public healthcare organization, wondering why the VMs were sluggish, only to realize the real bottleneck was the I/O queue on the shared datastore. We were looking at CPU metrics while the storage array was choking. Monitoring Linux server performance requires the right tool for the correct layer of the stack. You cannot rely on guesswork when systems degrade. In this guide, I compare 8 essential tools that help you isolate the saturated resource and identify the actual cause of the slowdown, saving you hours of blind troubleshooting. Understanding Linux performance monitoring is the difference between fixing a server at 3 AM in ten minutes or staring at logs until sunrise.
Prerequisites / Test Environment
You need a Linux server with root access to follow this guide. All these tools are available on Debian-based and RHEL-based distributions. On Ubuntu and derivatives, install the main packages with this command:
sudo apt install htop iotop nload glances sysstat -y
The sysstat package includes iostat and sar. For the examples, I will use a server with a mixed workload (web server and database) to show realistic outputs.
The Problem: You Know the Server Is Slow, Not Why Linux Performance Monitoring Is Vital
Slowness is a vague term. It means the application responds with a delay. It means queries take twice as long. It means page load times exceed your SLA. To fix the issue, you must classify the bottleneck. It falls into four categories: CPU, memory, disk I/O, and network. If you open a generic tool and look at data without an initial hypothesis, you get lost in the noise. The ability to conduct effective Linux performance monitoring depends on your ability to isolate the saturated resource.
top and htop — The Starting Point
The top command is present on every Linux system. It shows CPU usage, memory, and the process list sorted by consumption. Its interface is spartan and interactive, but often hard to read.
htop is its spiritual successor. It offers a color-coded interface, supports horizontal and vertical scrolling, lets you kill processes without typing the PID, and displays the process tree. When I connect to a slow server, htop is the first command I run.
To contextualize memory usage, I always pair htop with the free -h command. The -h flag shows values in a human-readable format (megabytes or gigabytes). Check the available column, not the free column. Linux uses free memory for the filesystem cache, so apparently low free memory does not indicate a problem. The available memory indicates how much RAM is actually recoverable if applications request it.
free -h
If available memory is less than 10% of total RAM, the server is swapping. Disk swap is hundreds of times slower than RAM. This is the most common cause of silent degradation.
glances — The All-in-One Dashboard
If you want a complete overview without switching windows, run glances. This Python tool gathers CPU, memory, swap, disk I/O, network, and processes into a single screen. It updates in real time and flags critical thresholds with different colors (red for dangerous values, magenta for warnings).
glances
Glances also offers a client-server mode. You can run glances -s on the remote server and connect from your PC with glances -c @SERVER_IP. This approach avoids opening an SSH session on the distressed server, reducing the additional load.
iostat and iotop — When the Disk Is the Problem
When the CPU seems high but processes consume no cycles, check the %iowait parameter in top or htop. A sustained %iowait value indicates the CPU is sitting idle waiting for the disk to complete read or write operations.
To analyze disk performance in detail, use iostat. The iostat -xz 1 command shows extended statistics updated every second. Look at the %util and await columns. If %util approaches 100%, the disk is saturated. If await exceeds 10-20 milliseconds for an SSD (or 50-100 for a mechanical drive), the device has a latency problem.
iostat -xz 1
To find out which process generates the I/O load, use iotop. The -o flag shows only the processes actually writing or reading, filtering out background noise.
sudo iotop -o
In an environment with heavy databases, I have seen iotop identify a hung Oracle query writing tens of megabytes per second to the temp file. Without iotop, I would have kept looking for a nonexistent CPU problem.
nload and ss — When the Network Is the Problem
If the disk and CPU are quiet, the bottleneck might be the network. To see real-time traffic on a specific interface, nload is immediate. It shows two graphs, one for incoming and one for outgoing traffic, with current and total traffic.
nload eth0
To understand which processes consume bandwidth, nethogs groups traffic by process. To verify which ports are listening and how many active connections exist on each, the ss command replaced netstat years ago.
ss -tulnp
The -t flag filters TCP connections, -u filters UDP, -l shows only listening ports, -n prevents domain name resolution, and -p shows the associated process. If you see hundreds of ESTABLISHED connections on a web server port, you might have a port exhaustion problem or a slow DDoS attack.
vmstat — CPU, Memory, and Swap at a Glance
vmstat is the Swiss Army knife of monitoring. It summarizes processes, memory, swap, I/O, system, and CPU in a single table. Run it specifying an update interval and a number of rows.
vmstat 2 10
This command prints 10 rows updated every 2 seconds. Ignore the first row, which shows averages since system boot. Look at the key columns. The b column under procs indicates processes blocked waiting for I/O. The si and so columns under swap indicate swap-in and swap-out memory respectively. If these values are continuously non-zero, the server needs more RAM. The wa column under cpu is the iowait percentage.
[Read also: SSH Hardening on Linux: Practical Guide 2026]
sar — Historical Performance Over Time
All the tools seen so far show real-time data. If the slowdown happened at 3 AM and you check at 9 AM, you see nothing. This is where sar comes in.
The sysstat package collects system metrics every 10 minutes via a cron job. You can query the history with the sar command followed by the time interval flag. For example, sar -u shows historical CPU usage, sar -r shows memory, and sar -d shows disk activity.
To view yesterday’s CPU usage:
sar -u -f /var/log/sysstat/sa$(date -d yesterday +%d)
Configure sysstat to retain data for at least 30 days by editing the /etc/sysstat/sysstat-config file and setting HISTORY=30. This allows you to compare server behavior over time and identify recurring patterns.
Prometheus + Grafana — Professional Monitoring for Production
For an infrastructure with multiple servers, SSHing into each machine is not scalable. Prometheus collects metrics via exporters (like node_exporter for Linux) and stores them in a time-series database. Grafana connects to Prometheus and visualizes the data in interactive dashboards.
The approach shifts from reactive to proactive. You configure alerts on Grafana or Alertmanager to receive a notification when iowait exceeds 20% for more than 5 minutes, or when swap exceeds 2GB. This is the standard for Linux performance monitoring in enterprise environments.
The official Prometheus documentation explains in detail how to configure metric scraping: https://prometheus.io/docs/prometheus/latest/configuration/configuration/
Comparative Table: When to Use Which Tool
To quickly choose the right tool for the situation, use this reference table.
| Problem | Symptom | Tool | Key Command |
|—|—|—|—|
| Saturated CPU | High Load Average, high %us | htop | htop |
| Slow Disk | High %iowait, processes in D state | iostat, iotop | iostat -xz 1, sudo iotop -o |
| Exhausted Memory | Active Swap, OOM killer | free, vmstat | free -h, vmstat 2 10 |
| Saturated Network | Maxed bandwidth, high latency | nload, ss | nload eth0, ss -tulnp |
| Global View | Unified real-time analysis | glances | glances |
| Past Slowdown | No current symptoms | sar | sar -u |
| Continuous Monitoring | Critical infrastructure | Prometheus + Grafana | Web Dashboard |
Common Errors and Troubleshooting
The first error is looking only at the CPU. A server with 20% CPU usage can be slow if 19% is iowait. The CPU waits for the disk and applications freeze.
The second error is trusting the free memory reported by top. As mentioned, the filesystem cache occupies free memory. Always check available memory with free -h.
The third error is lacking history. Without sar or Prometheus, an intermittent problem becomes impossible to diagnose. Install sysstat on your production servers today.
Finally, beware of the overhead of the tools themselves. Running glances or iotop on an already struggling server adds load. Use vmstat or iostat for minimal impact when resources are critical.
Conclusions with Operational Takeaways
Diagnosing performance problems on Linux requires method, not luck. Do not open top hoping to find the answer. Follow a logical order.
First step: check memory and swap with free -h and vmstat 2 10. If the server is swapping, you found the problem.
Second step: check iowait with vmstat and dig deeper with iostat -xz 1. If the disk is slow, use sudo iotop -o to find the guilty process.
Third step: if memory and disk are fine, check the CPU with htop and the network with nload eth0 and ss -tulnp.
Fourth step: install sar today so you are not caught unprepared the next time a slowdown happens overnight.
For environments with multiple servers, plan the migration to Prometheus and Grafana. Reactive monitoring is fine for troubleshooting. Proactive monitoring protects your SLA.