Skip to content
Innovialabs

High CPU or Memory on a Linux Server: How to Find the Cause

Practice4 min

In short

Start with top or htop to spot the culprit, use vmstat and iostat to tell CPU load from disk waits, and check free and dmesg to see whether memory is short and the OOM killer has fired.

The short answer

Diagnosis order:

  1. top or htop: who is using CPU and memory right now.
  2. vmstat 1: what limits the system, CPU, memory or I/O.
  3. iostat -x 1: whether the disk is the bottleneck.
  4. free -h and dmesg: how much memory is really available and whether the kernel killed processes.
  5. ps: history and details of a specific process.

vmstat and iostat usually come with the procps and sysstat packages.

How to read load average

top and uptime show three numbers: the average load over 1, 5 and 15 minutes. It is the number of processes running or waiting to run. On Linux it also counts processes waiting for disk (state D).

  • Compare load average with the number of cores (nproc). On 4 cores a value around 4 means full utilization, noticeably higher means a queue.
  • If load is high but the CPU is mostly idle, look at disk or network, not the processor.
  • A rising first number with calm others is a fresh spike, not a chronic issue.

Step 1. top and htop

In top, press P to sort by CPU and M to sort by memory. In htop, click a column or press F6.

Watch the %Cpu(s) line:

FieldWhat a high value means
usapplication code: heavy computation, an infinite loop
sykernel: many system calls, network traffic
waI/O wait: slow or overloaded disk
ststeal: neighbors on the hypervisor take CPU from your VPS

High st on a virtual machine cannot be fixed inside the OS; it is a question for the host or your plan.

Step 2. vmstat and iostat

vmstat 1 5
  • Column r is the CPU run queue. Consistently above the core count means not enough CPU.
  • b is processes blocked on I/O.
  • si and so are swap-in and swap-out. Constant non-zero values mean memory is short.
iostat -x 1 5

High %util and large await for a disk mean it cannot keep up. Find out who writes: iotop lists processes by I/O volume.

Step 3. Memory: free, swap and the OOM killer

free -h

Look at available, not free. Linux uses spare memory for file cache (buff/cache) and hands it to applications on demand, so a small free value is normal.

Swap is backup memory on disk. A little used swap is fine. The problem is constant swapping (si/so in vmstat), which makes the system crawl.

When memory and swap run out, the kernel starts the OOM killer and kills the process with the highest score. Check:

dmesg -T | grep -i -E "killed process|out of memory"
journalctl -k | grep -i oom

If an app "restarts by itself" with nothing in its own logs, the OOM killer is a frequent reason.

Step 4. ps: process details

ps aux --sort=-%cpu | head -n 10
ps aux --sort=-rss  | head -n 10
ps -o pid,etime,rss,cmd -p 1234

RSS is the real memory in use, etime is how long the process has been running. If a process's RSS only grows over time, suspect a leak.

Handling a runaway process

  1. Identify it: ps -fp PID, ls -l /proc/PID/exe, and which service it belongs to (systemctl status PID).
  2. Collect evidence before restarting: app logs, journalctl -u service, when the problem started. A restart wipes the clues.
  3. Lower its priority if the process is needed but disruptive: renice +10 -p PID.
  4. Stop it gracefully: kill PID (SIGTERM) first, and kill -9 PID only if that fails.
  5. If it is a cron job or an unknown process, check where it was launched from. An unexpected high-CPU process can be a miner left after a break-in.

Memory leak: step by step

  1. Confirm the growth: record the process RSS at intervals (ps in a loop or your monitoring).
  2. Tie the growth to events: a deploy, a specific route, a background job.
  3. Limit the damage: a memory cap via systemd (MemoryMax=) or Docker (mem_limit), so only that service fails, not the whole server.
  4. A scheduled restart works as a stopgap, not a fix.
  5. Find the cause with your language's profiler: unbounded caches, unclosed connections, event listeners nobody removes.

FAQ

Linux uses spare memory for file cache and releases it on demand. Look at the available column: that is how much memory applications can get without swapping.

We can help with this

If you'd rather get the result than figure it all out yourself — this is what we do every day.

Discuss a project

Read next

Have an idea or a task? Tell us about it

We'll reply within one business day and propose a solution. The consultation is free.