$linuxjunkies
>

How to Monitor Processes on Linux

Learn to monitor Linux processes with ps, top, htop, and btop. Covers reading process states, killing processes safely, and tuning CPU priority with nice/renice.

BeginnerUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • Terminal access (local or SSH)
  • sudo privileges for installing packages and raising process priority
  • Basic familiarity with navigating the Linux command line

Linux gives you several layers of visibility into running processes—from quick one-liners to full interactive dashboards. Knowing which tool to reach for, and how to act on what you see, is a daily skill for anyone managing Linux systems. This guide walks through the most useful utilities in order of complexity, then covers how to kill misbehaving processes and adjust their CPU priority.

Understanding Process States

Before firing up any tool, know what you're reading. Every process carries a single-character state code:

  • R – Running or runnable (on the CPU or waiting for a CPU slot)
  • S – Interruptible sleep (waiting for an event, e.g. I/O or a timer)
  • D – Uninterruptible sleep (usually stuck in a kernel I/O call; worrying if persistent)
  • Z – Zombie (process finished but parent hasn't collected its exit code)
  • T – Stopped (paused with SIGSTOP or Ctrl-Z)
  • I – Idle kernel thread (normal; seen in ps output for kernel workers)

A handful of D-state processes during heavy disk activity is normal. Many of them, or a persistent zombie count, signals a problem worth investigating.

Snapshot Monitoring with ps

ps prints a static snapshot of the process table. It reads /proc directly and exits immediately—useful in scripts and quick checks.

Common ps invocations

Show every process on the system in a readable format:

ps aux

The columns that matter most: %CPU, %MEM, STAT (process state), and COMMAND.

BSD-style (aux) and UNIX-style (-ef) are both widely supported. To see full command lines including arguments:

ps -ef

Filter to a specific process name without involving grep:

ps -C nginx

Show a process tree (who spawned what):

ps axjf

Sort by memory consumption, showing the top 10 consumers:

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

Real-Time Monitoring with top

top is installed on virtually every Linux system and needs no extra packages. It refreshes every 3 seconds by default and shows system-wide CPU, memory, and swap summaries at the top, followed by a live process list.

top

Key interactive commands inside top:

  • P – Sort by CPU usage (default)
  • M – Sort by memory usage
  • k – Kill a process (prompts for PID and signal)
  • r – Renice a process (change its priority)
  • 1 – Toggle per-CPU breakdown
  • q – Quit

Run top non-interactively for a single batch snapshot—handy in scripts:

top -b -n 1 | head -20

Interactive Monitoring with htop

htop is top with a modern ncurses interface: colour-coded CPU/memory meters per core, mouse support, and intuitive keybindings. Install it first if needed.

Install htop

# Debian / Ubuntu
sudo apt install htop

# Fedora / RHEL / Rocky
sudo dnf install htop

# Arch
sudo pacman -S htop
htop

Useful htop keybindings:

  • F6 or > – Choose sort column
  • F4 – Filter processes by name substring
  • F5 – Toggle tree view (shows parent/child relationships)
  • F9 – Send a signal to the selected process
  • Space – Tag a process; tagged processes can be acted on in bulk
  • u – Filter by a specific user

htop also shows individual thread counts and integrates lsof/strace shortcuts if those tools are installed.

Rich Monitoring with btop

btop (formerly bpytop) takes the dashboard concept further: GPU support (with optional plugin), network and disk I/O graphs, and a responsive layout that adapts to terminal size. It's the right choice when you want a persistent monitoring pane during troubleshooting sessions.

Install btop

# Debian / Ubuntu 22.04+
sudo apt install btop

# Fedora 37+
sudo dnf install btop

# Arch
sudo pacman -S btop

On older releases without a packaged version, grab a static binary from the btop GitHub releases page and place it in /usr/local/bin.

btop

Inside btop, press ? for a full keybinding reference. The process panel supports the same filter (f) and kill (k) workflow as htop.

Finding a Process by Name or Port

When you know the name but not the PID:

pgrep -la nginx

Output is PID followed by the full command — -a shows the command line, -l the name. Output will vary by what's running.

To find what process owns a listening port (requires ss, part of iproute2):

sudo ss -tlnp | grep ':80'

Killing and Signalling Processes

Processes communicate through signals. The most common:

SignalNumberMeaning
SIGTERM15Politely ask the process to exit (default for kill)
SIGKILL9Force-terminate immediately; process cannot catch or ignore this
SIGHUP1Reload configuration (convention; behaviour is process-defined)
SIGSTOP19Pause the process (like Ctrl-Z from a terminal)
SIGCONT18Resume a stopped process

Always try SIGTERM first. SIGKILL skips cleanup routines and can leave lock files or corrupt data.

# Graceful termination by PID
kill 1234

# Force-kill only if SIGTERM didn't work
kill -9 1234

# Kill all processes matching a name (careful with this)
pkill -TERM nginx

# Kill all processes matching a name, owned by a specific user
pkill -u www-data php-fpm

Adjusting Process Priority with nice and renice

Linux schedules CPU time partly based on a process's nice value, which ranges from -20 (highest priority) to +19 (lowest). Regular users can only lower priority (increase the nice value); root can raise it.

Start a new command with a lower priority so it doesn't compete with interactive work:

nice -n 15 tar -czf backup.tar.gz /home/user/data

Adjust the priority of an already-running process by PID:

# Lower priority (any user, for their own processes)
renice +10 -p 5678

# Raise priority (requires root)
sudo renice -5 -p 5678

In htop, select a process and press F7/F8 to decrement/increment nice value interactively.

Verifying What You See

Cross-check a suspicious process directly through /proc. Every PID has a directory there:

# Confirm the exact command line of PID 1234
cat /proc/1234/cmdline | tr '\0' ' '

# Check which user owns it
ls -l /proc/1234 | head -3

# See open file descriptors
ls -l /proc/1234/fd

Troubleshooting Common Issues

Process stuck in D state

Uninterruptible sleep almost always means the process is waiting on a kernel call—usually disk or NFS I/O. You cannot SIGKILL a process in D state; the kernel must release it. Check dmesg and your storage subsystem for I/O errors.

Zombie processes

Zombies are harmless individually—they consume only a PID slot—but if their count grows, the parent process has a bug. You cannot kill a zombie directly; killing or signalling its parent (SIGCHLD prompts a wait() call) will reap it. If the parent is systemd or PID 1, a reboot is the practical fix.

htop shows 100% CPU on one core constantly

Sort by CPU (P in top, or click the CPU% column in htop) and note the process name. Use strace -p PID to see what system calls it's making, or check its logs via journalctl -u servicename if it's a systemd unit.

tested on:Ubuntu 24.04Debian 12Fedora 40Arch rolling

Frequently asked questions

What is the difference between ps aux and ps -ef?
Both show all processes system-wide, but `ps aux` uses BSD syntax and includes a %CPU/%MEM column, while `ps -ef` uses UNIX syntax and adds the parent PID (PPID) column. The output is equivalent for most everyday use.
Why can't I kill a process even with kill -9?
SIGKILL cannot be caught or ignored, but it also cannot preempt a process stuck in uninterruptible sleep (D state). The kernel must release the process from its blocked I/O call first. Check for storage or NFS errors with `dmesg`.
What does a high nice value actually do?
A high nice value (e.g. +15 or +19) tells the Linux CFS scheduler to favour other processes over this one when CPU time is contested. The process still runs at full speed when the CPU is idle; the nice value only matters under load.
Is htop better than top for everyday use?
htop is more ergonomic—colour meters, mouse support, and tree view make it faster to use interactively. However, top ships on virtually every Linux installation without extra packages, so knowing top remains important for working on minimal or locked-down systems.
How do I find which process is listening on a specific port?
Run `sudo ss -tlnp | grep ':<port>'`. The output includes the PID and process name in the last column. You can then look up that PID in htop or with `ps -p PID`.

Related guides