Find out which process is using all your CPU or memory on Linux

Beginner 15 min Oct 31, 2026
Ubuntu 24.04 Ubuntu 22.04 Debian 12 Debian 11 AlmaLinux 9 Rocky Linux 9 Fedora 41

Learn how to identify which process is consuming your Linux server's CPU or memory using top, ps aux, and sort, then safely terminate runaway or zombie processes without guessing.

Prerequisites

  • SSH access to a Linux server
  • sudo or root privileges
  • Basic familiarity with the terminal

What this solves

A server that suddenly feels slow is almost always caused by one or two processes consuming most of the CPU or memory. This tutorial shows you how to read load average and process metrics, find the exact culprit with top and ps aux, and decide whether to kill it or investigate further.

This works the same way whether you are troubleshooting a web server, a database host, or a background worker.

Step-by-step diagnosis

Check the load average first

Load average shows how many processes are waiting for CPU time, averaged over 1, 5, and 15 minutes. On a system with 4 CPU cores, a load average above 4 means processes are queuing for CPU.

uptime

Check how many CPU cores you have to put that number in context.

nproc
Note: a high load average with low CPU usage usually points to processes stuck waiting on disk I/O or network, not CPU contention. See fix high load average with low CPU usage on web servers if that matches your case.

Open top for a live view

top gives you a real-time, auto-refreshing list of processes sorted by CPU usage by default.

top

Inside top, press Shift+M to sort by memory usage instead of CPU, and press Shift+P to go back to sorting by CPU. Press q to quit.

Note: the %CPU column can exceed 100% on multi-core systems because it reflects total CPU time across all cores, not a single core's capacity.

Understand RES vs VIRT

top shows several memory columns that are easy to misread. VIRT is the total virtual memory a process has mapped, including shared libraries and memory it has reserved but not touched. RES is the actual physical RAM the process is using right now, which is the number that matters for diagnosing memory pressure.

ColumnMeaningWhen to worry
VIRTTotal virtual memory mappedRarely, it is often inflated by shared libraries
RESPhysical RAM currently in useYes, this is real memory pressure
SHRMemory shared with other processesSubtract from RES to estimate unique usage
%MEMRES as a percentage of total system RAMYes, quick way to spot a memory hog

List processes with ps aux

ps aux gives you a one-time snapshot of every process, which is easier to pipe, grep, and sort than top's live view.

ps aux

The columns you care about are %CPU, %MEM, RSS (resident memory in KB), and COMMAND.

Sort ps aux by CPU usage

Sort the output by the %CPU column, descending, and show the top 10 processes.

ps aux --sort=-%cpu | head -n 11

The negative sign before %cpu means descending order. Remove it to sort ascending.

Sort ps aux by memory usage

Use the same pattern with %mem to find the biggest memory consumers.

ps aux --sort=-%mem | head -n 11

Filter for a specific process by name

If you already suspect a service, such as nginx or mysqld, filter ps output directly instead of scanning the whole list.

ps aux | grep -i mysqld | grep -v grep

The second grep removes the grep command itself from the results.

Identify zombie and defunct processes

A zombie process has finished executing but its exit status has not been collected by its parent process, leaving an entry in the process table. Zombies do not consume CPU or memory, but a large number of them can indicate a buggy parent process that never calls wait().

ps aux | awk '$8 ~ /Z/ {print}'

If you see zombies, the real fix is restarting the parent process, since you cannot kill a zombie directly, it is already dead and waiting to be reaped.

ps -o ppid= -p <zombie_pid>

Check per-process memory breakdown

For a deeper look at one process, including shared vs private memory, use the proc filesystem.

cat /proc/<pid>/status | grep -E 'VmRSS|VmSize|VmSwap'

Find out which user is running the heaviest processes

Sometimes the question is not which process, but which user or application owns it.

ps aux --sort=-%mem | awk 'NR==1 || NR<=10 {print $1, $2, $3, $4, $11}'

Terminate a runaway process safely

Always try a graceful termination first with the TERM signal, which asks the process to clean up and exit on its own.

kill -15 <pid>

Wait a few seconds and check if it is still running. Only use SIGKILL if the process ignores SIGTERM, since SIGKILL gives it no chance to close files or save state.

kill -9 <pid>
Warning: killing the wrong PID can take down an unrelated service. Double-check the PID with ps or top immediately before running kill, especially on shared or multi-tenant servers.

Kill all instances of a process by name

If a process is spawning multiple children, such as a misbehaving script or a leaked worker pool, killall targets every process matching a name.

killall -15 node

As with kill, escalate to SIGKILL only if the processes do not exit within a few seconds.

killall -9 node

Verify your setup

After terminating or restarting a process, confirm the resource usage has actually dropped.

uptime
ps aux --sort=-%cpu | head -n 5
free -h

free -h shows total, used, and available memory in human-readable units, which confirms whether memory was actually released.

When to investigate further vs when to restart a service

If a process is consuming high CPU briefly during a known workload, such as a backup job or a batch import, that is expected behavior, not a problem. Investigate further when CPU or memory usage climbs steadily over hours or days with no corresponding increase in traffic, since that pattern usually means a memory leak or an infinite loop in application code.

Restarting the service is the right short-term fix when you need the system responsive again immediately and you already know the service has a known leak that will be patched later. It is not a substitute for finding the root cause, since the same process will eventually degrade again.

Note: if the process holding resources is a database like PostgreSQL, check for connection exhaustion before killing anything. See fix PostgreSQL FATAL sorry, too many clients already for that specific case.

Common issues

SymptomCauseFix
top shows 100%+ CPU for one processProcess is using more than one core's worth of CPU timeDivide %CPU by number of cores with nproc to get true utilization
Process reappears after killIt is managed by systemd or a supervisor and gets auto-restartedStop the service properly with sudo systemctl stop servicename instead of killing the PID
kill -9 does nothingProcess is in uninterruptible sleep (D state), usually waiting on I/OInvestigate the underlying disk or NFS issue, SIGKILL cannot interrupt D state
Many Z state processesParent process is not reaping finished childrenRestart the parent process, you cannot kill a zombie directly
Free memory looks low but nothing seems to be using itLinux uses spare RAM for disk cache, which is reclaimableCheck the available column in free -h, not the free column
Permission denied when killing a processProcess is owned by another user or rootUse sudo kill -15 <pid>, never run your whole shell as root to avoid this

Next steps

Running this in production?

Want this handled for you? This works for a single server. When you run multiple environments or need this available 24/7, keeping it healthy is a different job, especially when a runaway process shows up at 3am. See how we run infrastructure like this for European teams.
#linux #top #ps aux #cpu usage #memory usage #process management #troubleshooting

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. Fully managed, with one fixed contact who knows your setup.

You get one fixed contact who knows your setup

Rotterdam 13:52 · reachable in a message, no ticket form