# What's Running: ps, top and htop

Every running program is a process with a number, its PID: ps lists the ones in your terminal, ps aux lists every one on the computer, ps aux --sort=-%cpu puts the busiest first, and top and htop show the same list live.

Apprentice · Unix · Linux · Updated November 10, 2026

## After this lesson you can

- List running processes with ps and ps aux, and read a line's PID, %CPU, %MEM and command
- Find the process using the most CPU or memory with ps aux --sort, top or htop

## Key takeaways

- A process is a program while it runs. Each one gets a number, its PID, and commands that stop or watch a process name it by that number.
- ps lists the processes in this terminal. ps aux lists every process on the computer, with its user, PID, %CPU, %MEM and command.
- A script shows up as bash followed by the script's name, because bash is the program running it.
- ps aux --sort=-%cpu | head -n 2 shows the busiest process. 100% CPU is one whole processor core.
- top and htop show the list live, busiest first, until you press q.

Your laptop was fine an hour ago. Now the fan is roaring, the battery is draining, and every click takes a second to answer. Something is working the computer hard, and you want to know what. On a desktop you'd open Task Manager, Activity Monitor or System Monitor. On a server, a Raspberry Pi or a cloud machine there's no window to open, and the same question is answered with `ps` and `top`. A developer asks it when a test run never finishes; an administrator asks it every time a server slows down.

## Every running program is a process

A recipe in a cookbook doesn't cook anything; a cook following it does. Programs work the same way. The file on the disk is the recipe, and each time it runs, the computer starts a **process**: the program at work. Two cooks can follow the same recipe at once, and two copies of a program are two processes. Like tickets at a deli counter, each process gets a number, its **process ID**, or **PID**.

`ps` (for *process status*) lists the processes running in your terminal:

```bash
ps
```

```text
    PID TTY          TIME CMD
   1722 pts/4    00:00:00 bash
   1802 pts/4    00:00:00 ps
```

Two processes: `bash`, the shell reading your commands, and `ps` itself, which was running while it made the list. `TTY` names the terminal they belong to (`pts/4` is a terminal window, read "pseudo-terminal 4"), and `TIME` is how much work the processor has done for each so far. Your numbers will be different: PIDs are handed out as programs start.

## Every process on the computer: ps aux

Make a practice folder with three small programs that misbehave on purpose. `runaway.sh` is stuck in a loop, counting as fast as it can; the other two are for the next lessons:

```bash
mkdir -p ~/terminal-practice/processes
cd ~/terminal-practice/processes
printf '%s\n' '#!/usr/bin/env bash' '# runaway.sh: stuck in a loop, counting as fast as it can, forever.' 'n=0' 'while true; do n=$((n + 1)); done' > runaway.sh
printf '%s\n' '#!/usr/bin/env bash' '# alarm.sh: beeps once a second until something stops it.' 'while true; do' '  echo "BEEP"' '  sleep 1' 'done' > alarm.sh
printf '%s\n' '#!/usr/bin/env bash' '# export-video.sh: pretends to export a video, one frame a second.' 'for frame in {1..600}; do' '  echo "Exported frame $frame of 600"' '  sleep 1' 'done' > export-video.sh
chmod +x runaway.sh alarm.sh export-video.sh
```

Open a second terminal window or tab (on Windows, a second Ubuntu tab), and start the runaway there:

```bash
cd ~/terminal-practice/processes
./runaway.sh
```

Nothing prints: it's busy counting. Back in the first terminal, plain `ps` still shows only `bash` and `ps`, because it lists this terminal's processes. `ps aux` lists every process on the computer, from every user (read the letters as *all users*, *user-friendly columns*, and processes with *no terminal* too). That's hundreds of lines, so pipe it into `grep` (*Finding Text: grep*) to keep the ones that mention the runaway:

```bash
ps aux | grep runaway
```

```text
sam         1826 99.8  0.0   4952  3648 pts/0    R+   07:32   0:26 bash ./runaway.sh
sam         2048  0.0  0.0   4132  2388 pts/4    S+   07:32   0:00 grep --color=auto runaway
```

The columns that matter most, from the left:

- **USER**: who started it, here sam.
- **PID**: its number, 1826.
- **%CPU**: how much of one processor core it's using. 99.8 is a whole core, busy every moment.
- **%MEM**: its share of the computer's memory, here almost none.
- **TTY**: `pts/0`, the second terminal.
- **COMMAND**: what's running. A script shows up as `bash` followed by the script's name, because bash is the program running it.

The second line is `grep` itself: it was running while `ps` looked, and its own command has *runaway* in it. Skip that line.

## Who's slowing things down? Sort the list

When you don't know the culprit's name yet, let `ps` sort. `--sort=-%cpu` puts the highest CPU first (the `-` means highest first), and `head -n 2` keeps the header and the top line:

```bash
ps aux --sort=-%cpu | head -n 2
```

```text
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
sam         1826 99.8  0.0   4952  3648 pts/0    R+   07:32   0:27 bash ./runaway.sh
```

There's the culprit. When a computer has run out of memory instead, sort by `-%mem`. The columns this lesson skips (memory in kilobytes, the state, the start time) are explained in `man ps`. On a Mac, `ps aux` works too, but its `ps` has no `--sort`: `ps aux -r` sorts by CPU, and `ps aux -m` by memory.

## A live view: top and htop

`ps` takes a snapshot. `top` keeps the list on the screen and updates it every few seconds, busiest first, until you press **q**. Plain `top` fills the screen with every process; `-p` and a PID watch only that one:

```bash
top -p 1826
```

```text
top - 07:33:03 up  3:56,  1 user,  load average: 0.50, 0.25, 0.26
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  4.3 us,  0.2 sy,  0.0 ni, 95.3 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st
MiB Mem :  64194.9 total,  60608.1 free,   1999.1 used,   2173.5 buff/cache
MiB Swap:  16384.0 total,  16384.0 free,      0.0 used.  62195.8 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   1826 sam       20   0    4952   3648   3360 R  99.7   0.0   0:34.56 bash
```

The five lines at the top are about the whole computer: how long it has been on, its processes, its processors and its memory. This computer has many processor cores, so as a whole it's only about 4% busy (`4.3 us`, work for user programs), while one core is flat out: that's the runaway's 99.7. Below them is one line per process, with columns much like `ps aux`'s. While `top` runs, **M** sorts by memory and **P** by CPU again. A Mac's `top` looks different; `top -o cpu` puts the busiest first.

**htop** is a friendlier `top`: a bar for each processor core and for memory, colors, and a list you can scroll with the arrow keys. Installing it changes your computer, so `sudo` asks for your password (*Installing Tools: Homebrew and apt*):

```bash
sudo apt install htop     # Ubuntu, and Ubuntu in WSL
brew install htop         # a Mac, with Homebrew
```

Run `htop`, press **F4** to filter, and type *runaway* to keep only its line. **q** quits.

![htop filtered to the word runaway: a bar for each processor core and one for memory across the top, and below them a single process line, bash ./runaway.sh, using about 100% CPU](https://www.ask-codey.com/lessons/TODO)

When you've seen enough, go back to the second terminal and press **Ctrl+C** to stop the runaway.

## Check yourself

2 questions to try on the lesson page.

## So what

When a computer slows down, `ps aux --sort=-%cpu` or `top` names the process doing it in seconds, on your laptop or on a server with no screen at all, and its PID is what you need to stop it.

## Key terms

- [Process](https://www.ask-codey.com/glossary/process)
- [ps](https://www.ask-codey.com/glossary/ps)
- [Process ID (PID)](https://www.ask-codey.com/glossary/process-id-pid)
- [top and htop](https://www.ask-codey.com/glossary/top-and-htop)

## Cheat sheets

- [What's Running: ps, top and htop](https://www.ask-codey.com/cheat-sheets/bash-processes-cheat-sheet)

## Related

- [Stopping Things: kill and Signals](https://www.ask-codey.com/lessons/bash-kill-and-signals)
- [Background Jobs: &, jobs, fg and bg](https://www.ask-codey.com/lessons/bash-background-jobs)
- [Finding Text: grep](https://www.ask-codey.com/lessons/bash-grep)

Source: https://www.ask-codey.com/lessons/bash-processes
