kmail.at
← learning

sysadmin · difficulty ◆◆

ps — snapshot running processes

A frozen moment of every process on the machine. No live updates, no drama.

`top` gives you a live, flickering dashboard. `ps` gives you a single frozen frame of every process — and one frame is usually all you need to find what is strangling the box.

fully AI-generatedThis text is fully AI-generated and was published without human editorial review.

2026-08-30 · 6 min read

$ ps

What it does

ps takes a snapshot of the current process table and prints it. Unlike top or htop, it is not interactive and not live — run it, get a list, done. That makes it the command to reach for inside scripts and one-liners, and the one you use when you just want to see the state of the machine at a single instant without babysitting a TUI.

Why it matters

Every sysadmin question that starts with "what is running" ends at ps: which process is using all the memory, which children did that service spawn, what is the PID I need to kill. Because its output is plain text, you can pipe it into grep, sort, awk, or wc and do real work with the result — top can't do that nearly as cleanly.

Example

$ ps aux --sort=-%mem | head -5
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
kmail      11878  1.6  9.3 8214948 1495844 ?     Ssl  Aug17 291:49 /home/kmail/.hermes/hermes-agent/venv/bin/python -m hermes_cli.main gateway run
root      345204  0.9  7.3 10276988 1176680 ?    Ssl  Aug29   6:43 /usr/local/bin/python3 -m uvicorn open_webui.main:app --host 0.0.0.0 --port 8080
root     2295363  1.7  2.7 8966520 448304 ?      Ssl  Aug19 274:04 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root     2296830  0.3  1.3 1322360 220848 ?      Ssl  Aug19  49:53 /app/.venv/bin/python /app/.venv/bin/fastapi run --host 0.0.0.0 src/main.py

The top-5 memory hogs. -%mem sorts by descending resident memory; the RSS column is what is actually in RAM.

$ ps -ef | grep uvicorn
root      345204     1  0 Aug29 ?        00:06:43 /usr/local/bin/python3 -m uvicorn open_webui.main:app --host 0.0.0.0 --port 8080 --forwarded-allow-ips * --workers 1 --ws-per-message-deflate true
kmail     99999 345204  0 09:12 pts/1    00:00:01 python3 -m uvicorn --reload app.main:app

-e shows full command lines and -f adds the parent PID (PPID 345204). grep uvicorn is the eternal way to find a service by name.

$ ps --ppid 1 -o pid=,comm=
444 multipathd
925 dbus-daemon
930 polkitd
937 systemd-logind
938 thermald

Every process whose parent is PID 1 — services adopted by systemd. -o customizes the columns (here just PID and command name).

$ ps -p 11878 -o pid,stat,etime,cmd
    PID STAT     ELAPSED CMD
  11878 Ssl   12-11:11:57 /home/kmail/.hermes/hermes-agent/venv/bin/python -m hermes_cli.main gateway run

Inspect one specific PID: ELAPSED shows it has been running 12 days 11 hours, STAT Ssl means sleeping, multi-threaded, session leader.

Common flags

aux
BSD style: all processes, user, full detail. The default everyone memorizes first
ef
System V style: all processes, full command line, plus parent PID in PPID
--sort=-%mem
sort output descending by memory or cpu (%cpu)
-o
choose columns precisely, e.g. -o pid,stat,etime,cmd
-p PID
show only the listed process(es) by PID
--ppid N
show only processes whose parent is N
-eo
every process, then custom columns (combine -e with -o)

History

Origin

ps is one of the oldest Unix commands, dating back to the earliest Bell Labs systems. The name is short for "process status". Because it predates any standardization, it supports two rival syntax styles: the original AT&T System V flags (leading dash: -ef) and the BSD style that dropped the dash (aux) — and modern ps accepts both, which is why the command has two mutually confusing looking invocations.

The procfs connection

On Linux, ps does not ask the kernel for a process list — it reads /proc, the pseudo-filesystem where every running process has a directory named after its PID (/proc/1, /proc/2, ...). That is why ps is instant and why /proc/sys exists for tunables. The procps-ng package provides both ps and top on most distros.

Fun facts

Pros & cons

pros

  • + Instant snapshot even on a thrashing box — reads /proc, no interaction
  • + Output is plain text, so it composes perfectly with grep, sort, awk, and wc
  • + Both flag styles plus precise column control (-o) for scripting

cons

  • − Only a frozen instant — for a live trend you still need top or htop
  • − The dual aux / -ef syntax confuses newcomers (and veterans) constantly
  • − RSS double-counts shared memory, so memory interpretation takes care
  • − Does not show process trees graphically; that is pstree's job

Takeaways

  1. 1Find memory hogs: `ps aux --sort=-%mem | head`
  2. 2Find CPU hogs: `ps aux --sort=-%cpu | head`
  3. 3Find a process by name: `ps -ef | grep name` (or `pgrep -f name`)
  4. 4Get the exact columns you need: `ps -eo pid,stat,etime,cmd`
  5. 5Grab one process's details with `ps -p <PID> -o pid,stat,cmd`

Related commands