Performance issues on Linux usually arrive as slow logins, delayed API responses, stalled batch jobs, or terminals that pause between keystrokes. Capturing a few short pressure snapshots while the symptom is happening helps separate CPU contention, memory pressure, storage wait, and network delay before the evidence disappears.
Start with host-wide counters before chasing individual processes. uptime shows whether work is queueing, vmstat shows runnable tasks, blocked tasks, swap movement, and I/O wait during the sample window, and ps identifies the process IDs that can be inspected or handled next.
Treat the first pass as triage rather than a benchmark. Avoid heavy load tests on an already slow host, keep samples short, and tie any restart, priority change, or process kill to one observed signal instead of guessing from a single high number.
Steps to troubleshoot performance issues in Linux:
- Capture the current load averages.
$ uptime 20:42:51 up 1 day, 8:47, 0 users, load average: 0.32, 0.46, 0.48
The three load averages cover the last 1, 5, and 15 minutes. Load includes runnable work and tasks stuck in uninterruptible I/O sleep, so a high value is not always CPU saturation.
Related: How to check load average in Linux
- Count the processors available to the current session.
$ nproc 8
Compare load averages with the CPU count available to the process. Containers, CPU affinity, and scheduler limits can make this lower than the physical host CPU count.
- Sample run queue, blocked tasks, swap, and I/O wait with vmstat.
$ vmstat 1 5 procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu------- r b swpd free buff cache si so bi bo in cs us sy id wa st gu 1 0 0 7497488 678080 3323428 0 0 17 1174 442 0 0 0 100 0 0 0 0 0 0 7497488 678080 3323428 0 0 0 0 206 279 0 0 100 0 0 0 0 0 0 7497488 678080 3323428 0 0 0 0 217 284 0 0 100 0 0 0 0 0 0 7497488 678080 3323428 0 0 0 0 441 649 0 0 100 0 0 0 0 0 0 7497488 678080 3323428 0 0 0 0 804 1041 0 0 100 0 0 0
Ignore a one-off spike and read the interval rows together. Persistent r near or above CPU count points toward CPU queueing, b shows blocked tasks, si and so show swap activity, and wa shows CPU time spent waiting on I/O.
- Check available memory and swap state.
$ free -h total used free shared buff/cache available Mem: 11Gi 966Mi 7.2Gi 29Mi 3.8Gi 10Gi Swap: 4.0Gi 0B 4.0GiLow free memory is not pressure by itself when available remains high. Treat sustained swap-in activity from vmstat or growing pressure counters as a stronger signal.
- List the current CPU-heavy processes.
$ ps -eo pid,user,stat,comm,pcpu,pmem --sort=-pcpu PID USER STAT COMMAND %CPU %MEM 3782 app R python3 96.4 4.8 2249 root Sl backup 8.1 1.0 1 root Ss systemd 0.3 0.3 686 message+ Ss dbus-daemon 0.0 0.1 ##### snipped #####The STAT column helps distinguish runnable tasks from blocked tasks. A D state usually means the task is waiting in uninterruptible I/O sleep.
- List the current resident-memory-heavy processes.
$ ps -eo pid,user,stat,comm,rss,pmem --sort=-rss PID USER STAT COMMAND RSS %MEM 3782 app R python3 524288 4.8 2249 root Sl backup 112640 1.0 311 root Ss systemd-journ 17368 0.4 1 root Ss systemd 12660 0.3 ##### snipped #####RSS is resident memory in KiB. Use it with %MEM to find processes holding physical memory, not just large virtual address spaces.
- Check per-device storage pressure when vmstat shows blocked tasks or I/O wait.
$ iostat -xz 1 3 Linux 6.12.76 (server) 06/13/26 (8 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 0.27 0.00 0.14 0.04 0.00 99.55 Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util vda 0.47 4.43 0.21 30.41 0.38 9.41 11.80 1171.89 48.09 80.29 1.86 99.29 4.10 15979.95 0.00 0.00 0.12 3894.32 6.98 0.19 0.02 0.32 ##### snipped #####iostat is usually provided by the sysstat package. High await or %util during the same window as application stalls points toward storage or virtual-disk latency.
Related: How to check CPU I/O wait in Linux
Related: How to show disk activity on Linux
Related: How to check disk errors in Linux - Measure network latency when only remote work is slow.
$ ping -c 4 1.1.1.1 PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data. 64 bytes from 1.1.1.1: icmp_seq=1 ttl=63 time=7.14 ms 64 bytes from 1.1.1.1: icmp_seq=2 ttl=63 time=6.80 ms 64 bytes from 1.1.1.1: icmp_seq=3 ttl=63 time=6.97 ms 64 bytes from 1.1.1.1: icmp_seq=4 ttl=63 time=7.87 ms --- 1.1.1.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3012ms rtt min/avg/max/mdev = 6.797/7.194/7.871/0.409 ms
Use the affected service hostname when DNS or load-balancer routing may be part of the slowdown. Use a stable comparison target only when the question is broader network path quality.
- Act on the confirmed bottleneck with the least disruptive change.
For a non-critical CPU-heavy process, lower priority before killing it. For memory pressure, move or restart the leaking workload during an approved window. For storage wait, pause the heavy write job and check disk errors. For remote-only delay, continue with network outage checks.
Related: How to change process priority in Linux
Related: How to kill a process in Linux
Related: How to check disk errors in Linux
Related: How to troubleshoot a Linux network outage - Repeat the vmstat sample after the change.
$ vmstat 1 5 procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu------- r b swpd free buff cache si so bi bo in cs us sy id wa st gu 0 0 0 7499276 678080 3323432 0 0 0 0 229 315 0 0 100 0 0 0 0 0 0 7499276 678080 3323432 0 0 0 0 226 305 0 0 100 0 0 0 0 0 0 7499276 678080 3323432 0 0 0 0 311 425 0 0 100 0 0 0 0 0 0 7499276 678080 3323432 0 0 0 0 218 296 0 0 100 0 0 0 0 0 0 7499276 678080 3323432 0 0 0 0 232 318 0 0 100 0 0 0
The original symptom should improve in the same window as the pressure signal. If the signal clears but the application remains slow, continue with application logs, service health, and dependency checks instead of repeating host-level triage.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.