ps system

ctrl+alt+del is not a diagnostic tool.

The ps man page is 1,400 lines long. You need one command and about 30 seconds.

You wanted to know what was eating your CPU. So you pressed Ctrl+Alt+Delete. You clicked “Task Manager.” You stared at a list of 187 processes, 160 of which are named svchost.exe. You sorted by CPU. It flickered. The numbers changed. You sorted again. It flickered again. You squinted at “System Idle Process” using 97% CPU and briefly panicked before realizing that’s a good thing. Then you scrolled through the list looking for something — anything — that looked suspicious. You found nothing. You closed Task Manager. You still don’t know what’s wrong.

On a Mac it’s even worse. You opened Activity Monitor from Spotlight because you can never remember where it lives. You stared at a beach ball of columns. You sorted by “% CPU” but it keeps jumping around because Activity Monitor itself is using 12% CPU to render its own interface. You briefly considered Googling “kernel_task high cpu mac” for the fourteenth time.

Meanwhile, the answer was always one command away.

Unless you’re running Windows then wtf none of this applies to you. But hey, come to the dark side, go install WSL2 and you can follow along. We’ll wait. Impatiently.

This page has distro-specific commands. Pick your poison:
Set it and forget it. Like your firewall rules. Wait—

If you’re lazy like me (all sysadmins are!) then click here for the ps cheat sheet.


Show me everything (the command you actually want)

ps aux

That’s it. Every process. Every user. CPU and memory usage. PIDs. Start times. The full command that launched it. One line per process, no flickering, no GUI, no beach ball.

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 169372 13284 ?        Ss   Mar14   0:03 /sbin/init
www-data  1842  2.3  1.4 524112 115392 ?       Sl   10:22   1:47 nginx: worker
postgres  2101  0.1  0.8 215444  68224 ?       Ss   Mar14   0:42 postgres
owner     9823 45.2  3.1 1842112 253440 pts/0  Rl+  11:15   5:33 node index.js

Your rogue process is right there. No scrolling through 187 svchost.exe entries. No wondering what “System Idle Process” is. Just data.

Sort by CPU usage

ps aux --sort=-%cpu | head -20

The top 20 processes by CPU usage. Descending. Instantly. Task Manager wishes it could sort this fast without redrawing the entire window.

Sort by memory usage

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

Same idea. Find whatever is eating your RAM. No right-clicking, no “Go to details,” no “Analyze wait chain.”


Find a specific process

You know what’s running. You want to find it. In Task Manager, you’d scroll. Or use the search box that appeared in Windows 10 and sometimes works.

ps aux | grep nginx

Every process with “nginx” in it. PID, CPU, memory, the full command. Done.

Avoid matching yourself

ps aux | grep [n]ginx

That bracket trick prevents grep from matching its own process in the list. It’s ugly but it works and you’ll feel clever every time you use it.

Or just use pgrep

pgrep -a nginx

Returns PIDs and command names. No grep. No bracket hack. Cleaner.

pgrep -u www-data

All processes owned by a specific user. For when you need to know what www-data is up to.


Kill processes

You found it. It’s misbehaving. Time to put it down.

Kill by PID

kill 9823

Sends SIGTERM. The process gets a chance to clean up and exit gracefully. This is the polite version.

Kill it harder

kill -9 9823

SIGKILL. No cleanup. No grace period. No negotiation. The process ceases to exist. Use this when SIGTERM didn’t work and you’re done being nice.

Kill by name

pkill nginx

Kills every process matching “nginx.” No PID required. Be very sure about what you’re killing because this doesn’t ask for confirmation.

pkill -u www-data

Kill every process owned by a user. Nuclear option. Use responsibly.

Kill everything matching a pattern

pkill -f "node.*server"

The -f flag matches against the full command line, not just the process name. For when you have twelve node processes and only want to kill the one running server.js.


Process trees (who spawned what)

ps auxf

The f flag adds ASCII tree formatting showing parent-child relationships. Now you can see that nginx master spawned four workers, or that systemd spawned everything because that’s what systemd does.

pstree -p

A cleaner tree view with PIDs. For when ps auxf is too dense and you just want the hierarchy.


Watch processes in real-time

ps is a snapshot — it shows you what’s happening right now. If you want a live, updating view:

top

It’s ps but it refreshes. Sort by CPU with P, by memory with M, kill a process with k. It’s been on every Unix system since 1984.

htop

top but prettier. Color-coded. Mouse support. Scroll through processes. Filter and search interactively. If htop isn’t installed:

sudo apt install htop
sudo dnf install htop

Your life gets marginally better.

Neither of these require you to press three keys simultaneously to open, which is already an improvement over Task Manager.


The flags that actually matter

Flag / Option What it does
a Show processes from all users, not just yours.
u Show the user/owner of each process with CPU and memory.
x Include processes not attached to a terminal (daemons, services).
f Forest view — show parent/child tree structure.
--sort=-KEY Sort by a column. - means descending. Common keys: %cpu, %mem, pid.
-p PID Show info for a specific PID only.
-u USER Show processes for a specific user.
-e Show every process (alternative to aux).
-o FORMAT Custom output columns (e.g., pid,user,%cpu,%mem,comm).

The aux combo is technically BSD-style syntax (no dash). -ef is System V style. Both work. Everyone uses aux. Don’t overthink it.


“But Task Manager—”

You’re adorable.

“Task Manager shows me everything I need.” Task Manager shows you a list of names, half of which are “Runtime Broker” and “Windows Shell Experience Host.” You don’t know what those are. Nobody knows what those are. Microsoft might not know what those are. ps aux shows you the actual command that launched each process, so you can, you know, understand what’s running on your own computer.

“Activity Monitor has a nice CPU graph.” A graph of what? Total CPU? Per-core? Per-process? It’s a wiggly line that tells you “something is happening” without telling you what. ps aux --sort=-%cpu | head -5 tells you exactly what, instantly, in text you can pipe to other commands.

“I can right-click and End Task.” And sometimes it works. And sometimes it doesn’t. And sometimes you get “Access Denied” on a process you can see but can’t touch. kill -9 doesn’t have a dialog box. It doesn’t ask if you’re sure. It just works.

“System Monitor on Linux has a GUI too.” Yes, and it uses more resources to display your resource usage than some of the processes you’re trying to monitor. That’s like hiring a second accountant to audit your first accountant’s expenses.

“I don’t need to kill processes often.” Then you don’t run enough software. Or you’ve never had a node process eat 4GB of RAM and refuse to die gracefully. It’s coming. And when it does, you’ll type pkill -f node and it’ll be over in a second.


ps cheat sheet

You made it. Or you skipped straight here. Either way, no judgment. Copy and paste these. Pin them. Tattoo them on your forearm. Whatever works.

What you’re doing Command
Show all processes ps aux
Top 20 by CPU ps aux --sort=-%cpu | head -20
Top 20 by memory ps aux --sort=-%mem | head -20
Find a process by name ps aux | grep [n]ginx
Find a process (cleaner) pgrep -a nginx
Process tree ps auxf
Kill by PID (graceful) kill PID
Kill by PID (force) kill -9 PID
Kill by name pkill processname
Kill by full command match pkill -f "pattern"
Kill all by user pkill -u username
Live process viewer htop (or top)
Custom columns ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu

The one command: ps aux — every process, every user, CPU, memory, PIDs, full commands. That’s 90% of what you need.

Back to the top, you overachiever.