How to Find the Process Using the Most CPU and Memory in Linux

When a Linux server slows down, the first question is almost always the same: what is eating the CPU or the memory? This guide walks through the tools that answer that question—from the ones on every system to the specialized utilities worth installing—along with the gotchas that trip people up (like why “used” memory rarely means what you think).

Quick answers

If you just need the command and want to move on:

# Top 10 processes by CPU
ps -eo pid,ppid,user,%cpu,%mem,comm --sort=-%cpu | head -n 11

# Top 10 processes by memory
ps -eo pid,ppid,user,%cpu,%mem,comm --sort=-%mem | head -n 11

The head -n 11 accounts for the header line plus 10 processes. Everything below explains what these numbers mean and when to reach for a better tool.

1. top — the tool that’s always there

top ships with virtually every Linux distribution, so it’s the reliable fallback:

top

By default top sorts by CPU usage. The interactive keys that matter most:

  • P — sort by CPU usage (the default)
  • M — sort by memory usage
  • N — sort by PID
  • T — sort by cumulative CPU time
  • k — kill a process (you’ll be prompted for the PID)
  • c — toggle between the command name and the full command line
  • 1 — expand per-CPU-core statistics
  • q — quit

Note that these sort keys are uppercase. A common point of confusion: the %CPU column can exceed 100% for multi-threaded processes, because a value of 100% represents one fully saturated core. On an 8-core machine, a busy process can legitimately show up to 800%.

Running top non-interactively

For scripts, logs, or a quick one-shot snapshot, use batch mode:

# One snapshot, sorted by memory, top 15 lines
top -b -o +%MEM -n 1 | head -n 15

# Same idea for CPU
top -b -o +%CPU -n 1 | head -n 15
  • -b runs in batch mode (plain text, no screen control).
  • -n 1 takes a single iteration and exits.
  • -o sets the sort field.

2. htop — a friendlier, interactive top

htop is not always preinstalled, but it’s worth adding:

# Debian/Ubuntu
sudo apt install htop

# RHEL/Fedora/CentOS
sudo dnf install htop

It gives you colored per-core meters, scrolling, mouse support, and easy sorting. Inside htop:

  • F6 (or click a column header) — choose the sort field
  • F4 — filter processes by name
  • F3 — search
  • F5 — toggle the process tree view
  • F9 — send a signal (kill)
  • H — hide/show user threads
  • u — filter by a specific user

The tree view (F5) is particularly useful for spotting a parent process that has spawned many children—a frequent cause of runaway resource usage.

See also: Mastering the Linux Command Line — Your Complete Free Training Guide

3. ps — the scriptable snapshot

ps is ideal when you want a precise, one-time list you can pipe into other commands. Two equivalent, widely used forms:

# BSD-style syntax, sorted by CPU
ps aux --sort=-%cpu | head

# Explicit column selection, sorted by memory
ps -eo pid,ppid,user,%mem,%cpu,rss,comm --sort=-%mem | head

Useful column choices for -eo:

  • pidppid — process and parent process IDs
  • %cpu%mem — percentage of CPU and physical memory
  • rss — resident set size in KB (actual physical RAM used)
  • vsz — virtual memory size in KB (usually much larger; see the caveats below)
  • comm — the command name only
  • args (or cmd) — the full command line, helpful when many processes share a name

The leading - in --sort=-%cpu means descending order. Drop it for ascending.

A caveat about %CPU in ps

Unlike top, the %CPU reported by ps is an average over the entire lifetime of the process, not an instantaneous reading. A process that hammered the CPU at startup and is now idle may still show a high number. For a live view, tophtop, or pidstat are better.

4. pidstat — sampling over time

When you need to see which process is busy right now and how that changes, pidstat (from the sysstat package) samples at an interval:

sudo apt install sysstat     # Debian/Ubuntu
sudo dnf install sysstat     # RHEL/Fedora

# CPU usage, refreshed every 1 second
pidstat -u 1

# Memory usage, every 2 seconds
pidstat -r 2

# Both CPU and memory for a specific PID, every second
pidstat -u -r -p 1234 1

Because pidstat measures deltas between samples, its CPU numbers reflect current activity rather than a lifetime average—closer to what top shows.

5. Getting accurate memory figures

This is where most quick answers go wrong. The RSS (resident set size) reported by ps and top counts shared memory—like shared libraries—against every process that maps it. If ten processes each link libc, that memory is counted ten times. Summing RSS therefore overstates real usage.

The more honest metric is PSS (proportional set size), which divides shared pages evenly among the processes using them. The smem tool reports it:

sudo apt install smem        # Debian/Ubuntu
sudo dnf install smem        # RHEL/Fedora

# Processes sorted by PSS, human-readable sizes
smem -rk

# Aggregate by application name instead of per-process
smem -rk -P <name>

You can also read a single process’s resident memory straight from /proc:

grep VmRSS /proc/1234/status

For a system-wide picture of memory (not per process), use:

free -h

Pay attention to the available column rather than free. Linux deliberately uses spare RAM for the page cache, so “free” memory is usually low by design; “available” estimates what applications can actually claim without swapping.

6. atop and glances — richer monitors

Two more tools go beyond CPU and memory to give a fuller system view:

  • atop records historical data and can highlight resource-heavy processes, including disk and network I/O per process. It can even replay past activity from its logs—useful for diagnosing an incident after the fact.
  • glances is a cross-platform monitor (written in Python) that shows CPU, memory, disk, network, and per-process stats on one screen, with optional web and API modes.
sudo apt install atop glances

7. Memory and CPU by control group

On modern systems where services run under systemd, resource usage is often best understood per cgroup (i.e., per service) rather than per process:

systemd-cgtop

This sorts control groups by CPU, memory, or I/O and makes it obvious when a single service—rather than a lone process—is responsible for the load. Inside containers, the same idea applies; tools like docker stats expose per-container CPU and memory.

Putting it together: a practical workflow

  1. Start broad. Run top or htop to see whether the pressure is CPU, memory, or both, and whether it’s one process or many.
  2. Confirm CPU over time. If CPU is the issue, use pidstat -u 1 to watch live usage and identify the persistent offender (not just a startup spike).
  3. Get memory right. If memory is the issue, don’t trust summed RSS. Use smem -rk for PSS, and check free -h‘s available column for the real headroom.
  4. Attribute to a service. Use systemd-cgtop (or docker stats) to tie the usage back to a service or container rather than a bare PID.
  5. Act deliberately. Once you’ve identified the culprit, decide whether to renice it (renice), limit it (cgroups / systemd resource controls), restart the service, or fix the underlying cause—killing a process with kill is a last resort, not a fix.

Summary

GoalBest toolCommand
Quick interactive looktoptop (press P or M)
Nicer interactive UIhtophtop
Scriptable snapshotpsps aux --sort=-%cpu | head
Live CPU over timepidstatpidstat -u 1
Accurate memory (PSS)smemsmem -rk
System memory overviewfreefree -h
Per-service usagesystemd-cgtopsystemd-cgtop

The tools on every Linux box—topps, and free—will answer the question most of the time. The specialized ones (pidstatsmematopsystemd-cgtop) matter when you need accuracy over time or an honest accounting of shared memory. Knowing which number you’re actually looking at is what turns a guess into a diagnosis.

Avatar photo
David Cao

David is a Cloud & DevOps Enthusiast. He has years of experience as a Linux engineer. He had working experience in AMD, EMC. He likes Linux, Python, bash, and more. He is a technical blogger and a Software Engineer. He enjoys sharing his learning and contributing to open-source.

Articles: 275

Leave a Reply

Your email address will not be published. Required fields are marked *