Processes and jobs
top
Show a live, sorted view of processes and system load; batch mode prints snapshots for logs and scripts.
top [-b] [-n ITERATIONS] [-d SECONDS] [-p PID,...] [-u USER] [-o FIELD]
top redraws a table of processes every few seconds, sorted by CPU use by default, under a
summary header: uptime and load average, task counts by state, CPU time split (us user, sy
kernel, wa waiting on I/O, st stolen by the hypervisor) and memory and swap totals. It is the
first thing to run when a machine feels slow: the top line tells you whether it is CPU, I/O wait
or memory, and the process list tells you who.
Interactively, a few keys do most of the work: P sorts by CPU, M by memory, c toggles full
command lines, 1 splits the CPU line per core, k kills a process by PID, u filters by
user, H shows threads, q quits. Those keys need a terminal; none of them can be shown here.
With -b (batch mode) top writes plain text to standard output instead of drawing on the
screen, and -n limits how many updates it prints. That is the form for scripts, logs and
remote one-off checks (ssh host 'top -b -n 1 | head -20'), and the one used below. The
examples run in a container that shares the build machine's kernel, so the header's uptime, load
and memory figures describe that machine; the examples cut the header off and show only the
process list, which is the part that belongs to the sandbox. Header lines are the first five,
then a blank line, so the column header is line 7.
Examples
Print one snapshot of the process list
top -b -n 1 | tail -n +7
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 253812 18280 5988 S 0.0 0.0 0:23.48 python3
8 root 20 0 11768 3360 2136 S 0.0 0.0 0:00.10 sshd
3465 dev 20 0 4488 2356 2096 S 0.0 0.0 0:00.00 bash
3466 dev 20 0 7800 4132 2100 R 0.0 0.0 0:00.00 top
3467 dev 20 0 3048 1420 1312 S 0.0 0.0 0:00.00 tail -b writes plain text and -n 1 stops after one update. tail -n +7 skips the five summary
lines and the blank line. PR and NI are the scheduling priority and nice value, VIRT,
RES and SHR memory in KiB, S the state and TIME+ CPU time as minutes:seconds.hundredths.
Find the process that is burning CPU
python3 -c 'while True: pass' &
sleep 1
top -b -n 1 -o %CPU | sed -n '7,10p'
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3469 dev 20 0 14860 6776 4020 R 100.0 0.0 0:01.19 python3
1 root 20 0 253812 18280 5988 S 10.0 0.0 0:23.54 python3
8 root 20 0 11768 3360 2136 S 0.0 0.0 0:00.10 sshd A busy loop in the background, then one snapshot sorted by %CPU (also the default).
%CPU is measured over the last interval and is per core, so a multi-threaded process can
show more than 100 on a multi-core machine.
Watch specific processes over time
python3 -c 'while True: pass' &
top -b -n 3 -d 0.5 -p $! | grep -A1 '^ *PID'
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3474 dev 20 0 14860 6692 3932 R 100.0 0.0 0:00.20 python3
--
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3474 dev 20 0 14860 6692 3932 R 100.0 0.0 0:00.70 python3
--
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3474 dev 20 0 14860 6692 3932 R 100.0 0.0 0:01.20 python3 -p limits the display to the listed PIDs (comma-separated), -d 0.5 sets the
interval in seconds and -n 3 prints three updates. grep -A1 keeps each column header and
the line after it; TIME+ grows by about half a second of CPU per update.
Show only one user's processes, with full command lines
sleep 300 &
top -b -n 1 -c -u dev -w 100 | tail -n +7
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3477 dev 20 0 4488 2400 2144 S 0.0 0.0 0:00.00 /bin/bash -c sleep 300 & to+ 3478 dev 20 0 3012 1428 1320 S 0.0 0.0 0:00.00 sleep 300 3479 dev 20 0 7804 4184 2144 R 0.0 0.0 0:00.00 top -b -n 1 -c -u dev -w 100 3480 dev 20 0 3048 1408 1292 S 0.0 0.0 0:00.00 tail -n +7
-u dev filters by effective user, -c shows the command line instead of the program
name, and -w 100 widens the output to 100 columns. A + at the end of a column marks a
value that did not fit.
Sort by memory use
python3 -c 'import time; x = bytearray(50_000_000); time.sleep(30)' &
sleep 0.5
top -b -n 1 -o RES | sed -n '7,10p'
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3482 dev 20 0 63692 55712 4128 S 0.0 0.0 0:00.03 python3
1 root 20 0 253812 18280 5988 S 0.0 0.0 0:23.64 python3
3484 dev 20 0 7800 4172 2136 R 0.0 0.0 0:00.00 top -o FIELD picks the sort column by its header name: RES (resident memory), %MEM,
TIME+, PID. Prefix it with - (-o -RES) to sort ascending. The Python process holding
a 50 MB buffer comes first.
Show task memory in larger units
python3 -c 'import time; x = bytearray(50_000_000); time.sleep(30)' &
sleep 0.5
top -b -n 1 -e m -p $! | tail -n +7
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3487 dev 20 0 62.2m 54.4m 4.0m S 0.0 0.0 0:00.03 python3
-e scales the per-process memory columns: k, m, g, t or p. With m the values are
MiB with a trailing m. (-E does the same for the summary header.)
Show the threads of a process
python3 -c 'import threading, time
for _ in range(2): threading.Thread(target=time.sleep, args=(30,)).start()' &
sleep 0.3
top -b -n 1 -H -p $! | tail -n +7
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3492 dev 20 0 162360 7572 4344 S 0.0 0.0 0:00.00 python3 3494 dev 20 0 162360 7572 4344 S 0.0 0.0 0:00.00 python3 3495 dev 20 0 162360 7572 4344 S 0.0 0.0 0:00.00 python3
-H lists each thread as its own line. The PID column then holds thread IDs; all three
lines belong to one Python process (the main thread plus two workers), which is why they
share the same memory figures.
Record snapshots to a file for later
python3 -c 'while True: pass' &
top -b -n 3 -d 0.5 -p $! > top.log
grep -c '^top -' top.log
awk '$1 ~ /^[0-9]+$/ {print $9, $11}' top.log
3 100.0 0:00.20 100.0 0:00.70 100.0 0:01.20
Each update starts with a top - line, so counting them confirms three snapshots. The awk
line pulls %CPU and TIME+ from the process rows. On a server, top -b -d 60 -n 1440 >
day.log keeps a day of minute-by-minute history without installing anything.
List the fields top can display
top -O | head -12
PID PPID UID USER RUID RUSER SUID SUSER GID GROUP PGRP TTY
-O prints every field name and exits; these are the names -o accepts for sorting. Adding
or removing columns is done interactively with f and saved with W to the config file.
Forgetting batch mode in a script
top -n 1 | head -3
echo "top exit status: ${PIPESTATUS[0]}"
top: failed tty get top exit status: 1
Without -b, top needs a terminal to draw on. With output going to a pipe and no
terminal it fails with failed tty get and exit status 1. Any top in a cron job, script or
CI log needs -b.
Common pitfalls
Leaving out
-bin scripts and cron jobs:topfails without a terminal, or fills a log with screen-control escape codes when one exists. Alwaystop -b -n 1.Reading
%CPUabove 100 as a bug. It is per core: 400 on an 8-core machine means four cores' worth. Press1(or read the header) to see per-core load, andItoggles Irix mode, which divides by the core count.Judging memory pressure by the
freefigure. Linux uses spare memory as cache; look atavail Memin the header (orfree -h'savailablecolumn) instead.In a container, the header shows the host's CPU count, load and memory, while the process list shows only the container's processes.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
macOS
topis a different program: batch output istop -l 1(-lis the sample count), sorting is-o cpuor-o mem(lowercase keys), and there is no-b.FreeBSD
topuses-bfor batch mode too, but its sort keys (-o cpu,-o res) and other options differ from procps.htopandbtopare friendlier interactive alternatives on any system, but they are not installed by default; scripts should stick totop -borps.
Options worth knowing
A selection, described in our own words. For the full list, see top(1) or top --help.
| Option | What it does |
|---|---|
-b, --batch-mode | Write plain text to standard output instead of drawing on the screen. |
-n, --iterations NUMBER | Exit after NUMBER updates. |
-d, --delay SECONDS | Wait SECONDS (fractions allowed) between updates. |
-p, --pid PIDLIST | Show only the listed process IDs (comma-separated). |
-u, --filter-only-euser USER | Show only processes whose effective user is USER. |
-U, --filter-any-user USER | Show only processes where any user ID (real, effective, saved) matches USER. |
-o, --sort-override FIELD | Sort by FIELD (a column name such as %MEM or RES); a leading - reverses. |
-O, --list-fields | Print all field names and exit. |
-c, --cmdline-toggle | Toggle between program names and full command lines. |
-H, --threads-show | Show each thread as its own line. |
-i, --idle-toggle | Toggle display of idle processes. |
-S, --accum-time-toggle | Toggle cumulative time (include dead children's CPU time). |
-e, --scale-task-mem SCALE | Show process memory in k, m, g, t or p units. |
-E, --scale-summary-mem SCALE | Show header memory in k, m, g, t, p or e units. |
-w, --width[=COLUMNS] | In batch mode, set the output width. |
-1, --single-cpu-toggle | Toggle between one combined CPU line and one per CPU. |
-s, --secure-mode | Run in secure mode, disabling interactive kill and renice. |
-V, --version | Print the version and exit. |
Related
psPrint a snapshot of running processes, with the columns, filters and sort order you choose.pgrepPrint the PIDs of processes whose name (or full command line) matches a pattern, with filters by user, parent and age.killSend a signal to processes by PID or job number; by default TERM, which asks a process to exit.reniceChange the niceness (CPU scheduling priority) of processes that are already running, by PID, process group or user.freeShow how much RAM and swap is in use, free, and available to new programs.uptimeShow how long the system has been running, how many users are logged in, and the load averages.vmstatReport processes, memory, swap, I/O and CPU activity, once or at a regular interval.