Linux Process Management Cheat Sheet

Most used
ps aux --sort=-%cpu | head       # top CPU users
pgrep -a firefox                # PIDs and command lines matching a name
kill 12345                      # ask PID 12345 to exit (SIGTERM)
pkill -f 'python app.py'        # same, matching the full command line
top                             # live view (press P for CPU, M for memory, q to quit)
nohup ./job.sh > job.log 2>&1 &  # run in the background, survives logout

Every running program is a process with a numeric PID, an owner and a parent. Most tools here come from procps-ng (ps, top, pgrep, pkill, kill) and are installed everywhere. htop and btop are optional extras in every distro's repositories. Processes started by systemd services should be managed with systemctl, not killed by hand, or systemd will just restart them.

Listing processes with ps

CommandWhat it does
ps auxEvery process, BSD style: user, PID, %CPU, %MEM, state, command
ps -efEvery process, System V style, including the parent PID (PPID)
ps -ef --forestShow the parent/child tree
pstree -pCompact process tree with PIDs
ps aux --sort=-%mem | headBiggest memory users first
ps -u aliceProcesses owned by a user
ps -p 1234 -o pid,ppid,user,stat,etime,cmdChosen columns for one PID (etime = running time)
ps -C nginx -o pid,rss,cmdSelect by exact command name
ps -eLfShow threads
ps -eo pid,stat,cmd | awk '$2 ~ /^[DZ]/'Processes stuck in D (I/O wait) or Z (zombie) state

STAT letters: R running, S sleeping, D uninterruptible I/O wait, T stopped, Z zombie. Extra flags: < high priority, N low priority, s session leader, + foreground.

Finding processes

CommandWhat it does
pgrep nginxPIDs whose name contains nginx
pgrep -a nginxPIDs with full command lines
pgrep -f 'manage.py runserver'Match against the whole command line
pgrep -u www-data -lProcesses of one user, with names
pidof sshdPIDs of an exact program name
sudo ss -ltnpWhich process listens on which TCP port
sudo lsof -i :443Processes using a port
sudo fuser -v /mnt/usbProcesses using a file or mount point
sudo lsof -p 1234Files, sockets and libraries opened by a PID
systemctl status 1234Which systemd unit (service, scope) a PID belongs to

Live monitoring: top and htop

Command or keyWhat it does
topLive process list, refreshed every 3 seconds
top -o %MEMStart sorted by memory
top -u aliceOnly one user's processes
top -b -n 1 | head -20One snapshot in batch mode (for scripts and logs)
top keys: P M TSort by CPU, memory, time
top keys: 1 c HPer-CPU lines, full command, show threads
top keys: k rKill or renice a PID from inside top
htopFriendlier top: scroll, mouse, tree view (F5), search (F3), filter (F4), kill (F9)
btopFull-screen dashboard with CPU, memory, disk and network graphs
systemd-cgtopCPU and memory per service or user slice
uptime / cat /proc/loadavgLoad averages over 1, 5 and 15 minutes
free -hRAM and swap usage (look at the available column)

Tracking down something that keeps the fans spinning? Follow the high CPU and memory usage guide.

Signals: kill, pkill, killall

CommandWhat it does
kill PIDSend SIGTERM (15): polite request to exit
kill -9 PID (kill -KILL PID)SIGKILL: immediate, cannot be caught. Last resort.
kill -HUP PIDSIGHUP: many daemons reload their configuration
kill -STOP PID / kill -CONT PIDPause and resume a process
kill -INT PIDSIGINT: same as pressing Ctrl+C
kill -lList all signal names and numbers
pkill firefoxSIGTERM to every process whose name matches
pkill -f 'node server.js'Match the full command line
pkill -u aliceEvery process of a user (logs them out)
killall -w nginxKill by exact name and wait until they have exited
kill -- -PGIDSignal a whole process group (negative number)
sudo systemctl kill --signal=KILL app.serviceKill every process of a service

Priority: nice, renice, ionice

CommandWhat it does
nice -n 19 tar czf backup.tgz /dataStart a command with the lowest CPU priority (range -20 to 19)
renice -n 10 -p 1234Lower the priority of a running process
sudo renice -n -5 -p 1234Raise priority (negative values need root)
renice -n 15 -u aliceChange every process of a user
ionice -c3 rsync -a src/ dst/Idle I/O class: only use the disk when nothing else needs it
ionice -c2 -n7 -p 1234Lowest best-effort I/O priority for a running PID
taskset -c 0,1 cmdPin a command to CPUs 0 and 1
systemd-run --user -p CPUQuota=50% cmdHard cap a command at half of one CPU

Jobs, background and logout

Command or keyWhat it does
cmd &Start in the background of the current shell
Ctrl+ZSuspend the foreground job
bg / bg %2Continue a suspended job in the background
fg / fg %2Bring a job back to the foreground
jobs -lList this shell's jobs with PIDs
kill %1Signal a job by job number
nohup cmd > out.log 2>&1 &Ignore the hangup signal so the command survives logout
disown -h %1Detach an already running job from the shell
setsid cmdRun in a new session with no controlling terminal
systemd-run --user --unit=myjob cmdRun as a transient systemd unit (logs in the journal)
waitIn a script, wait for background jobs to finish

For interactive work you want to come back to, tmux is easier than nohup.

Common recipes

Stop a frozen program gracefully, then forcefully if it ignores you:

pkill -f myapp; sleep 5; pgrep -f myapp && pkill -9 -f myapp

Free a port that something is still holding (see Address already in use):

sudo ss -ltnp 'sport = :8080'
sudo kill "$(sudo lsof -t -i :8080)"

Top 10 processes by real memory (RSS), in MiB:

ps -eo rss,pid,comm --sort=-rss | head -11 | awk 'NR==1{print;next}{printf "%7.1f %s %s\n",$1/1024,$2,$3}'

Find out why a process was killed unexpectedly (often the OOM killer, see Out of memory: Killed process):

journalctl -k -b | grep -iE 'killed process|out of memory'

Find the parent of a zombie and restart it:

ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/'
ps -p PARENT_PID -o pid,cmd

Run a heavy job without hurting interactive use:

nice -n 19 ionice -c3 make -j"$(nproc)"

Gotchas

  • Do not reach for kill -9 first. SIGKILL gives the program no chance to save state or remove lock files, which is a common cause of "database is locked" and dpkg lock errors afterwards.
  • pkill matches substrings. pkill sh also kills bash, ssh and zsh. Preview with pgrep -a, or anchor: pkill -x sh.
  • Process names are cut to 15 characters for pgrep and pkill without -f.
  • Services come back. Killing a process that belongs to a unit with Restart= starts a new one. Use systemctl stop.
  • Load average is not CPU percent. It counts processes running or waiting, including D-state I/O waits. A load of 8 on an 8-core machine is fully busy, not overloaded.
  • %CPU over 100. In top and ps, 100% is one core. A multi-threaded program can show 400% on a 4-core machine. Press I in top to switch to Irix-off mode.
  • nohup still dies when systemd-logind kills user processes at logout (KillUserProcesses=yes, set on some distros). tmux sessions are killed too in that case. Use systemd-run --user plus loginctl enable-linger.

References: ps(1), top(1) and signal(7).

Frequently asked questions

How do I kill a process by name?

Use pkill name (matches part of the process name) or killall name (exact name). Check what would match first with pgrep -a name.

What is the difference between kill and kill -9?

Plain kill sends SIGTERM, which asks the program to exit and lets it clean up. kill -9 sends SIGKILL, which the kernel enforces immediately, so temporary files, locks and unsaved data can be left behind. Use -9 only when SIGTERM does not work.

How do I keep a command running after I log out?

Start it with nohup cmd &, or run it inside tmux or screen. For a long-running service, a systemd unit or systemd-run --user is the most reliable option.

Why can't I kill a process even with kill -9?

It is probably in state D (uninterruptible sleep), waiting on disk or network I/O such as a dead NFS mount, or it is a zombie (state Z) that is already dead and waiting for its parent. Fix the I/O or kill the parent.

How do I find which process uses a port?

Run sudo ss -ltnp 'sport = :8080' or sudo lsof -i :8080. The output includes the process name and PID.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.