Process management cheatsheet.
List processes
ps aux # all processes, BSD style
ps -ef # all, full format
ps -eLf # threads too
ps aux | grep nginx
pgrep -fl nginx # PID + cmdline
pgrep -u alice
pidof nginx
Tree view
pstree
pstree -p # with PIDs
pstree -u # with users
pstree alice # for user
top / htop / btop
top
htop # interactive, better
btop # most modern
In htop: F4 filter, F5 tree, F9 kill, F10 quit.
Resource breakdowns
ps aux --sort=-%cpu | head
ps aux --sort=-%mem | head
ps -eo pid,user,pcpu,pmem,comm,args --sort=-pcpu | head
Kill
kill PID
kill -9 PID # SIGKILL (last resort)
kill -TERM PID # graceful (default)
kill -HUP PID # reload
killall nginx
pkill -f "python script"
Signals
TERM (15) default; graceful
INT (2) ctrl-c
HUP (1) hangup; many daemons reload
QUIT (3) ctrl-\; core dump
KILL (9) unblockable
USR1, USR2 custom signals
STOP, CONT pause/resume
kill -l # list all
Send signal to many
pkill -SIGTERM nginx
killall -USR1 nginx # reopen logs
Jobs / fg / bg
cmd & # background
jobs # list
fg %1 # foreground
bg %1 # background
ctrl-z # suspend
disown %1 # remove from job table
nohup cmd & # outlive shell
nice / renice
nice -n 19 cmd # low priority (1-19; 19 lowest)
nice -n -5 cmd # high priority (requires root)
renice -n 10 -p PID
ionice
ionice -c 3 cmd # idle I/O
ionice -c 2 -n 7 cmd # best-effort low
ionice -c 1 -n 0 cmd # realtime (root)
taskset (CPU affinity)
taskset -c 0,1 cmd # pin to cores 0,1
taskset -p 0x3 PID # bitmask
strace
strace cmd
strace -p PID # attach
strace -f -p PID # follow forks
strace -e network cmd # only network syscalls
strace -c cmd # summary
ltrace
ltrace cmd # library calls
lsof
lsof -p PID # open files
lsof -i # all sockets
lsof -i :80 # what's on port 80
lsof /var/log/nginx.log # who has this file open
lsof -u alice
lsof +D /var/log # under dir
/proc/PID
cat /proc/PID/cmdline
cat /proc/PID/status
cat /proc/PID/limits
cat /proc/PID/environ # env vars (NUL separated)
ls -la /proc/PID/fd/ # open file descriptors
cat /proc/PID/io # I/O stats
time
time cmd
# real user sys
/usr/bin/time -v cmd shows more (memory, syscalls).
Run on schedule
at 14:00 << EOF
backup.sh
EOF
atq # list jobs
crontab -e
# m h dom mon dow command
0 2 * * * /opt/backup.sh
systemd-run (one-off as service)
systemd-run --unit=temp --slice=user.slice -p MemoryMax=200M cmd
Run with resource limits + as a unit.
Limit resources per process
prlimit --as=536870912 cmd # 512MB virtual memory limit
ulimit -v 524288 # 512MB (same)
ulimit -t 60 # 60s CPU
ulimit -n 4096 # max open files
ulimit -u 100 # max processes
Background long-running
nohup cmd > out.log 2>&1 &
echo $! # PID
Or screen / tmux:
tmux new -s mywork
# inside: ctrl-b d to detach
tmux ls
tmux attach -t mywork
Process states
R running
S sleeping (interruptible)
D uninterruptible sleep (usually I/O wait)
Z zombie (finished, awaiting parent)
T stopped
ps -eo pid,state,comm | grep D
D state = process stuck on I/O. Hardware or NFS issue often.
Wait for process
wait PID # in shell, wait for background
In scripts.
Common mistakes
kill -9first instead of TERM → loses graceful shutdown.ps aux | grep Xmatches the grep itself; usepgrep -fl.- Forgetting
-fflag to match full cmdline. - High
niceon critical daemon → bad UX. - Not detaching long-running commands (lose on SSH disconnect).
Read this next
If you want my process monitoring scripts, they’re at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .