ZetCode

Linux top and htop Commands

last modified October 23, 2026

The top command shows a live view of the running system: load, CPU and memory usage, and a list of processes sorted by CPU consumption, refreshed every few seconds. It answers the classic questions "why is the machine slow?" and "which process is eating the memory?". htop is a more user-friendly alternative with colour meters, scrolling, mouse support, and a tree view. top is part of procps-ng and is installed everywhere; htop usually has to be installed with the package manager (sudo apt install htop).

The examples use top from procps-ng 4.0.2 and htop 3.2.2. They ran in a container on a machine with eight CPUs; the summary lines therefore describe the whole machine, while the process list shows the processes of the container: two CPU-bound Python processes (one of them started with nice -n 10), a process holding 200 MiB of memory, a process with three worker threads, and a few idle ones. The screens of the interactive programs were captured from a terminal after the keys described in each section were pressed; on a real terminal they are in colour.

Starting top

Without options, top fills the terminal and refreshes every three seconds. It is left with q.

top

The upper part, the summary area, describes the whole system; the lower part lists processes, the busiest first. The two Python processes at the top each use a full CPU, which top shows as 100%. The next sections explain the fields.

$ top
top - 19:42:07 up  9:34,  0 user,  load average: 2.21, 1.62, 1.18
Tasks:  11 total,   3 running,   8 sleeping,   0 stopped,   0 zombie
%Cpu(s): 14.0 us,  0.2 sy, 12.5 ni, 73.1 id,  0.0 wa,  0.0 hi,  0.1 si,  0.0 st
MiB Mem :  15787.1 total,    658.2 free,  12217.9 used,   3999.6 buff/cache
MiB Swap:   2048.0 total,    209.0 free,   1839.0 used.   3569.2 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:08.15 python3
     22 jano      20   0   16288   9276   5608 R  99.7   0.1   0:08.15 python3
     29 jano      20   0  239780  11804   5784 S   6.0   0.1   0:00.51 python3
      1 jano      20   0    7088   3624   3284 S   0.0   0.0   0:00.01 bash
     17 jano      20   0    8508   3984   3108 S   0.0   0.0   0:00.00 tmux: server
     18 jano      20   0    7204   3892   3336 S   0.0   0.0   0:00.00 bash
     26 jano      20   0  221092 214136   5668 S   0.0   1.3   0:00.07 python3
     31 jano      20   0    5472   1816   1716 S   0.0   0.0   0:00.00 sleep
     33 root      20   0    8120   3976   3588 S   0.0   0.0   0:00.00 sudo
     35 root      20   0    5472   1820   1716 S   0.0   0.0   0:00.00 sleep
     41 jano      20   0   11644   5352   3240 R   0.0   0.0   0:00.00 top

The summary area

The first line shows the current time, how long the system has been up, the number of logged-in users, and the load average: the average number of processes that are running or waiting for the CPU (or for disk I/O) over the last 1, 5, and 15 minutes. A load equal to the number of CPUs means full utilization; a higher load means that processes are queuing. The second line counts tasks by state; zombies are finished processes whose parent has not collected their exit status.

The CPU line shows how the CPU time of all CPUs together is spent, in percent:

FieldMeaning
ususer space processes
sythe kernel
niuser processes with a positive nice value (low priority)
ididle
waidle while waiting for disk or network I/O
hi, sihardware and software interrupts
ststeal: time taken by the hypervisor for other virtual machines

On our eight-CPU machine, one fully busy CPU is 12.5% of the total; this is why the niced Python process appears as about 12.6% ni. A high wa points to slow disks; a high st on a cloud server to an overloaded host.

The memory lines show total, free, used, and buffer/cache memory, and swap. Free memory is usually low, because Linux uses spare memory for the disk cache, which it gives back on demand. The best indicator is avail Mem, an estimate of how much memory new programs can get without swapping.

Process columns

The default columns of the process list have the following meaning.

ColumnMeaning
PIDprocess ID
USEReffective user
PR, NIscheduling priority and nice value; for normal processes, PR is 20 plus the nice value
VIRTvirtual memory size in KiB, including memory that is reserved but never used
RESresident memory: the physical RAM the process actually uses
SHRthe part of RES that may be shared with other processes, such as libraries
Sstate: R running, S sleeping, D uninterruptible sleep (usually I/O), T stopped, Z zombie, I idle kernel thread
%CPUshare of one CPU since the last refresh; a multithreaded process can exceed 100
%MEMRES as a percentage of total memory
TIME+total CPU time used, in minutes, seconds, and hundredths
COMMANDprogram name, or the full command line

For memory usage, RES is the column that matters. In our example, the process holding 200 MiB of data has a RES of about 214,000 KiB, while the threaded process has a large VIRT but uses only about 12 MiB.

Batch mode

The -b option runs top in batch mode: it writes plain text to standard output instead of controlling the terminal. Combined with -n, the number of iterations, it produces snapshots for scripts, logs, and bug reports.

top -bn1 | head -n 15

-bn1 is short for -b -n 1. In batch mode, lines are cut at 80 columns unless the COLUMNS variable or the -w option says otherwise, so long names end with +. Note that the CPU line of the first iteration is not meaningful; the next section shows why.

$ top -bn1 | head -n 15
top - 19:42:08 up  9:34,  0 user,  load average: 2.19, 1.63, 1.18
Tasks:  12 total,   3 running,   9 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,100.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  15787.1 total,    658.3 free,  12217.8 used,   3999.6 buff/cache
MiB Swap:   2048.0 total,    209.0 free,   1839.0 used.   3569.3 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     22 jano      20   0   16288   9276   5608 R 100.0   0.1   0:09.15 python3
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:09.15 python3
     29 jano      20   0  239780  11804   5784 S   6.7   0.1   0:00.58 python3
      1 jano      20   0    7088   3696   3348 S   0.0   0.0   0:00.01 bash
     17 jano      20   0    8508   3984   3108 S   0.0   0.0   0:00.00 tmux: s+
     18 jano      20   0    7204   3892   3336 S   0.0   0.0   0:00.00 bash
     26 jano      20   0  221092 214136   5668 S   0.0   1.3   0:00.07 python3
     31 jano      20   0    5472   1816   1716 S   0.0   0.0   0:00.00 sleep

Delay and iterations

The -d option sets the refresh interval in seconds, and -n the number of refreshes before top exits.

top -b -d 1 -n 3 -p "$(pgrep -n -f cruncher)" | grep -E '^(top|%Cpu| +[0-9])'

Percentages are computed from the difference between two samples. For the first screen, top has only a very short interval to work with, and the summary CPU line shows nonsense such as 100% idle while two CPUs are busy. The second and later iterations are correct. To capture CPU usage in a script, use top -b -d 1 -n 2 and keep only the second iteration.

$ top -b -d 1 -n 3 -p "$(pgrep -n -f cruncher)" | grep -E '^(top|%Cpu| +[0-9])'
top - 19:42:17 up  9:34,  0 user,  load average: 2.18, 1.63, 1.19
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:18.26 python3
top - 19:42:18 up  9:34,  0 user,  load average: 2.16, 1.64, 1.19
%Cpu(s): 14.5 us,  0.7 sy, 12.5 ni, 72.1 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:19.26 python3
top - 19:42:19 up  9:34,  0 user,  load average: 2.16, 1.64, 1.19
%Cpu(s): 14.9 us,  0.6 sy, 12.5 ni, 71.8 id,  0.0 wa,  0.0 hi,  0.1 si,  0.0 st
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:20.26 python3

Sorting

The -o option sets the sort field by its column name.

top -bn1 -o %MEM | head -n 12 | tail -n 6
top -bn1 -o TIME+ | sed -n '7,10p'

Sorting by %MEM brings the memory-hungry process to the top. Sorting by TIME+ shows the processes that have consumed the most CPU time since they started, which reveals long-running consumers even when they are idle at the moment. A minus sign before the name, as in -o -%MEM, sorts from low to high.

$ top -bn1 -o %MEM | head -n 12 | tail -n 6
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     26 jano      20   0  221092 214136   5668 S   0.0   1.3   0:00.07 python3
     29 jano      20   0  239780  11804   5784 S   0.0   0.1   0:00.58 python3
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:09.31 python3
     22 jano      20   0   16288   9276   5608 R 100.0   0.1   0:09.31 python3
     54 jano      20   0   11632   5368   3320 R   0.0   0.0   0:00.00 top
$ top -bn1 -o TIME+ | sed -n '7,10p'
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     22 jano      20   0   16288   9276   5608 R 100.0   0.1   0:09.46 python3
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:09.46 python3
     29 jano      20   0  239780  11804   5784 S   6.7   0.1   0:00.59 python3

Sorting interactively

In interactive mode, single keys change the sort order: P sorts by CPU, M by memory, T by time, and N by PID. The < and > keys move the sort column left and right, and R reverses the order.

top
M

After pressing M, the process list is sorted by resident memory. The keys are case-sensitive; lowercase letters have other meanings.

$ top
top - 19:42:15 up  9:34,  0 user,  load average: 2.18, 1.63, 1.19
Tasks:  11 total,   3 running,   8 sleeping,   0 stopped,   0 zombie
%Cpu(s): 14.1 us,  0.3 sy, 12.6 ni, 72.8 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
MiB Mem :  15787.1 total,    658.3 free,  12217.8 used,   3999.4 buff/cache
MiB Swap:   2048.0 total,    209.0 free,   1839.0 used.   3569.3 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     26 jano      20   0  221092 214136   5668 S   0.0   1.3   0:00.07 python3
     29 jano      20   0  239780  11804   5784 S   6.7   0.1   0:00.97 python3
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:15.48 python3
     22 jano      20   0   16288   9276   5608 R 100.0   0.1   0:15.48 python3
     62 jano      20   0   11632   5512   3412 R   0.0   0.0   0:00.00 top
     17 jano      20   0    8508   3984   3108 S   0.0   0.0   0:00.00 tmux: server
     33 root      20   0    8120   3976   3588 S   0.0   0.0   0:00.00 sudo
     18 jano      20   0    7204   3892   3336 S   0.0   0.0   0:00.00 bash
      1 jano      20   0    7088   3700   3348 S   0.0   0.0   0:00.02 bash
     35 root      20   0    5472   1820   1716 S   0.0   0.0   0:00.00 sleep
     31 jano      20   0    5472   1816   1716 S   0.0   0.0   0:00.00 sleep

Showing one user's processes

The -u option shows only the processes of a user; in interactive mode, the u key asks for the user name.

top -bn1 -u root | sed -n '7,$p'

The user can be given as a name or a UID. With -U, top matches the real, effective, saved, or file system user, which also finds processes that have switched users. A ! before the name, as in -u '!root', excludes the user.

$ top -bn1 -u root | sed -n '7,$p'
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     33 root      20   0    8120   3976   3588 S   0.0   0.0   0:00.00 sudo
     35 root      20   0    5472   1820   1716 S   0.0   0.0   0:00.00 sleep

Monitoring specific processes

The -p option limits top to a comma-separated list of PIDs, up to twenty.

top -bn1 -p "$(pgrep -d, -f cruncher)"

pgrep -d, prints the PIDs of the matching processes separated by commas, exactly the format that -p expects. The Tasks line now counts only the monitored processes; the other summary lines still describe the whole system.

$ top -bn1 -p "$(pgrep -d, -f cruncher)"
top - 19:42:17 up  9:34,  0 user,  load average: 2.18, 1.63, 1.19
Tasks:   2 total,   2 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  15787.1 total,    583.1 free,  12292.8 used,   4055.3 buff/cache
MiB Swap:   2048.0 total,    209.0 free,   1839.0 used.   3494.3 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     22 jano      20   0   16288   9276   5608 R 100.0   0.1   0:17.79 python3
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:17.79 python3

Full command lines

By default, the COMMAND column shows only the program name, and all our Python scripts appear as python3. The -c option, or the c key, shows the full command line.

top -bn1 -c -w 100 -o %CPU | sed -n '7,12p'

Now we can see which script each process runs. The -w option sets the output width in batch mode, so the command lines are not cut.

$ top -bn1 -c -w 100 -o %CPU | sed -n '7,12p'
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     22 jano      20   0   16288   9276   5608 R 100.0   0.1   0:17.95 python3 cruncher.py
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:17.94 python3 cruncher.py
     29 jano      20   0  239780  11804   5784 S   6.7   0.1   0:01.12 python3 threads.py
      1 jano      20   0    7088   3700   3348 S   0.0   0.0   0:00.02 -bash
     17 jano      20   0    8508   3984   3108 S   0.0   0.0   0:00.00 tmux new-session -d -s main

Threads

The -H option, or the H key, lists individual threads instead of processes.

top -bn1 -H -w 100 -p "$(pgrep -f threads.py)" | sed -n '7,$p'

Each thread has its own ID, shown in the PID column, and its own CPU time. The memory columns are the same for all threads, because they share the memory of the process. Python sets the thread names, which top shows in thread mode. This view helps to find which thread of a server is busy.

$ top -bn1 -H -w 100 -p "$(pgrep -f threads.py)" | sed -n '7,$p'
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     29 jano      20   0  239780  11804   5784 S   6.7   0.1   0:01.13 python3
     36 jano      20   0  239780  11804   5784 S   6.7   0.1   0:00.41 Thread-1 (work)
     37 jano      20   0  239780  11804   5784 S   6.7   0.1   0:00.33 Thread-2 (work)
     38 jano      20   0  239780  11804   5784 S   6.7   0.1   0:00.35 Thread-3 (work)

Per-CPU usage

The 1 key toggles between one summary line for all CPUs and one line per CPU.

top
1

Two CPUs are fully busy: on one, all of the time is user time (us), and on the other, mostly nice time (ni), which belongs to our niced process. The scheduler moves processes between CPUs, so the busy pair changes over time. A single CPU at 100% while the others are idle is a sign of a single-threaded bottleneck. The t and m keys switch the CPU and memory lines to bar graphs.

$ top
top - 19:42:25 up  9:34,  0 user,  load average: 2.15, 1.65, 1.20
Tasks:  11 total,   3 running,   8 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.0 us,  0.0 sy, 99.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  1.0 si,  0.0 st
%Cpu1  :  4.3 us,  1.3 sy,  0.0 ni, 88.6 id,  3.7 wa,  0.0 hi,  2.0 si,  0.0 st
%Cpu2  :  4.7 us,  1.0 sy,  0.0 ni, 93.6 id,  0.0 wa,  0.0 hi,  0.7 si,  0.0 st
%Cpu3  : 20.3 us,  0.3 sy,  0.0 ni, 79.1 id,  0.3 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  :  3.7 us,  0.3 sy,  0.0 ni, 95.7 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu5  :  2.7 us,  0.7 sy,  0.0 ni, 96.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  :  5.4 us,  1.0 sy,  0.0 ni, 93.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  : 83.0 us,  0.7 sy,  0.0 ni, 16.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  15787.1 total,    597.4 free,  12277.9 used,   4025.0 buff/cache
MiB Swap:   2048.0 total,    209.0 free,   1839.0 used.   3509.2 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     22 jano      20   0   16288   9276   5608 R 100.0   0.1   0:26.27 python3
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:26.27 python3
     29 jano      20   0  239780  11804   5784 S   6.0   0.1   0:01.62 python3
      1 jano      20   0    7088   3700   3348 S   0.0   0.0   0:00.03 bash
     17 jano      20   0    8508   3984   3108 S   0.0   0.0   0:00.00 tmux: server
     18 jano      20   0    7204   3892   3336 S   0.0   0.0   0:00.00 bash

Filtering by field

The o key adds a filter in the form FIELD=value (substring match), FIELD>number, or FIELD<number; O does the same with case-sensitive matching, and = clears all filters.

top
o
COMMAND=python3
c

We pressed o, typed COMMAND=python3 and Enter, and then c for full command lines. Only the Python processes remain. Other useful filters are %CPU>5.0 and !COMMAND=kworker, which excludes matches.

$ top
top - 19:42:36 up  9:35,  0 user,  load average: 2.20, 1.67, 1.21
Tasks:  11 total,   3 running,   8 sleeping,   0 stopped,   0 zombie
%Cpu(s): 14.3 us,  0.4 sy, 12.6 ni, 70.9 id,  1.7 wa,  0.0 hi,  0.3 si,  0.0 st
MiB Mem :  15787.1 total,    535.2 free,  12338.2 used,   4017.5 buff/cache
MiB Swap:   2048.0 total,    209.0 free,   1839.0 used.   3448.9 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     22 jano      20   0   16288   9276   5608 R 100.0   0.1   0:37.28 python3 cruncher.py
     24 jano      30  10   16288   9420   5756 R 100.0   0.1   0:37.28 python3 cruncher.py
     29 jano      20   0  239780  11804   5784 S   6.7   0.1   0:02.29 python3 threads.py
     26 jano      20   0  221092 214136   5668 S   0.0   1.3   0:00.07 python3 cache.py

Memory units

The -E option sets the unit of the summary memory lines, and -e the unit of the process memory columns. The units are k, m, g, t, p, and e.

top -bn1 -E g -e m | sed -n '1,12p'

The summary is now in GiB and the process memory in MiB. In interactive mode, the E and e keys cycle through the units.

$ top -bn1 -E g -e m | sed -n '1,12p'
top - 19:42:39 up  9:35,  0 user,  load average: 2.18, 1.68, 1.22
Tasks:  12 total,   3 running,   9 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
GiB Mem :     15.4 total,      0.5 free,     12.0 used,      3.9 buff/cache
GiB Swap:      2.0 total,      0.2 free,      1.8 used.      3.4 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     22 jano      20   0   15.9m   9.1m   5.5m R 100.0   0.1   0:39.44 python3
     24 jano      30  10   15.9m   9.2m   5.6m R 100.0   0.1   0:39.44 python3
     29 jano      20   0  234.2m  11.5m   5.6m S   6.7   0.1   0:02.43 python3
      1 jano      20   0    6.9m   3.6m   3.3m S   0.0   0.0   0:00.03 bash
     17 jano      20   0    8.3m   3.9m   3.0m S   0.0   0.0   0:00.01 tmux: s+

Renicing and killing

top can change the priority of a process with the r key and send it a signal with the k key. Both ask for a PID, defaulting to the process at the top of the list, and then for the nice value or the signal.

top -o %MEM
r
PID of cache.py
5
ps -o pid,ni,cmd -p "$(pgrep -f cache.py)"

We pressed r, entered the PID of the memory-holding process, and the nice value 5. The process now runs with nice 5, which raises its PR to 25; ps confirms it. Normal users can only increase the nice value of their own processes; lowering it requires root. The k key works the same way and defaults to SIGTERM.

$ top -o %MEM
top - 19:42:49 up  9:35,  0 user,  load average: 2.31, 1.72, 1.24
Tasks:  11 total,   3 running,   8 sleeping,   0 stopped,   0 zombie
%Cpu(s): 16.0 us,  0.4 sy, 12.6 ni, 70.7 id,  0.1 wa,  0.0 hi,  0.2 si,  0.0 st
MiB Mem :  15787.1 total,    553.7 free,  12320.0 used,   4017.5 buff/cache
MiB Swap:   2048.0 total,    209.0 free,   1839.0 used.   3467.1 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     26 jano      25   5  221092 214136   5668 S   0.0   1.3   0:00.07 python3
     29 jano      20   0  239780  11804   5784 S   6.6   0.1   0:03.08 python3
     24 jano      30  10   16288   9420   5756 R  99.7   0.1   0:49.45 python3
     22 jano      20   0   16288   9276   5608 R  99.7   0.1   0:49.46 python3
    121 jano      20   0   11624   5500   3412 R   0.0   0.0   0:00.00 top
     17 jano      20   0    8508   3992   3108 S   0.0   0.0   0:00.01 tmux: server
     33 root      20   0    8120   3976   3588 S   0.0   0.0   0:00.00 sudo
$ ps -o pid,ni,cmd -p "$(pgrep -f cache.py)"
    PID  NI CMD
     26   5 python3 cache.py

Interactive keys of top

The most useful keys in interactive top are summarized below; h shows the full help.

KeyAction
qQuit
hHelp
P, M, T, NSort by CPU, memory, time, PID
<, >, RMove the sort column, reverse the order
1Per-CPU lines
cFull command lines
HThreads
VProcess tree (forest view)
iHide idle processes
uShow one user
o, O, =Add a filter, case-sensitive filter, clear filters
k, rKill, renice
dChange the refresh interval
E, eMemory units
fChoose and order columns
z, xColours, highlight the sort column
WSave the settings to ~/.config/procps/toprc

htop

htop shows the same information in a friendlier way.

htop

At the top are bars for each CPU and for memory and swap, next to the task count, the load average, and the uptime. The process list shows full command lines by default and can be scrolled with the arrow keys or the mouse. Unlike top, htop lists the threads of a process as separate rows, so threads.py appears four times; the H key hides user threads. The bottom line shows the function keys. MEM% is based on RES, and memory sizes are shown with units such as M and G.

$ htop

    0[|||||||||||||||||||||||||||||||||||||||||100.0%]   4[|                                           2.0%]
    1[||                                         2.7%]   5[||                                          3.3%]
    2[||                                         1.3%]   6[|                                           2.0%]
    3[||||||||||||||||||||                      40.7%]   7[|||||||||||||||||||||||||||||||            62.7%]
  Mem[||||||||||||||||||||||||||||||||||||10.9G/15.4G] Tasks: 11, 3 thr, 0 kthr; 3 running
  Swp[||||||||||||||||||||||||||||||||||||1.76G/2.00G] Load average: 2.36 1.75 1.25
                                                       Uptime: 09:35:27

  [Main] [I/O]
    PID USER       PRI  NI  VIRT   RES   SHR S  CPU%▽MEM%   TIME+  Command
     22 jano        20   0 16288  9276  5608 R 100.9  0.1  0:54.56 python3 cruncher.py
     24 jano        30  10 16288  9420  5756 R 100.3  0.1  0:54.55 python3 cruncher.py
     29 jano        20   0  234M 11804  5784 S   6.7  0.1  0:03.45 python3 threads.py
     36 jano        20   0  234M 11804  5784 S   2.7  0.1  0:01.18 python3 threads.py
     37 jano        20   0  234M 11804  5784 S   2.7  0.1  0:01.13 python3 threads.py
     38 jano        20   0  234M 11804  5784 S   2.0  0.1  0:01.09 python3 threads.py
      1 jano        20   0  7088  3708  3348 S   0.0  0.0  0:00.04 -bash
     17 jano        20   0  8508  3996  3108 S   0.0  0.0  0:00.02 tmux new-session -d -s main
     18 jano        20   0  7204  3892  3336 S   0.0  0.0  0:00.00 -bash
     26 jano        25   5  215M  209M  5668 S   0.0  1.3  0:00.07 python3 cache.py
     31 jano        20   0  5472  1816  1716 S   0.0  0.0  0:00.00 sleep 9999
     33 root        20   0  8120  3976  3588 S   0.0  0.0  0:00.00 sudo sleep 8888
     35 root        20   0  5472  1820  1716 S   0.0  0.0  0:00.00 sleep 8888
    139 jano        20   0  7648  4104  3496 R   0.0  0.0  0:00.00 htop
F1Help  F2Setup F3SearchF4FilterF5Tree  F6SortByF7Nice -F8Nice +F9Kill  F10Quit

Tree view and user filter

The -t option starts htop in tree view, and -u shows one user's processes. In the program, the F5 or t key toggles the tree, and u selects the user.

htop -t -u jano

The tree shows which process started which: the container's login shell started a tmux server, which runs a shell with htop in it; the Python processes are children of the login shell as well. The tree view makes it easy to find the parent of a runaway process or to see all workers of a server together. A whole subtree can be collapsed with - and expanded with +.

$ htop -t -u jano

    0[|||||||||||||||||||||||||||||||||||||||||100.0%]   4[|                                           0.7%]
    1[|||                                        4.0%]   5[||                                          2.7%]
    2[||                                         2.7%]   6[||                                          4.0%]
    3[|||||||||||||||||||||||||||||||||||||||||100.0%]   7[||                                          3.4%]
  Mem[||||||||||||||||||||||||||||||||||||10.9G/15.4G] Tasks: 11, 3 thr, 0 kthr; 3 running
  Swp[||||||||||||||||||||||||||||||||||||1.76G/2.00G] Load average: 2.36 1.75 1.25
                                                       Uptime: 09:35:31

  [Main] [I/O]
    PID△USER       PRI  NI  VIRT   RES   SHR S  CPU% MEM%   TIME+  Command
      1 jano        20   0  7088  3708  3348 S   0.0  0.0  0:00.04 -bash
     17 jano        20   0  8508  4004  3108 S   0.0  0.0  0:00.02 ├─ tmux new-session -d -s main
     18 jano        20   0  7204  3892  3336 S   0.0  0.0  0:00.00 │  ├─ -bash
    148 jano        20   0  7676  4048  3452 R   0.0  0.0  0:00.00 │  └─ htop -t -u jano
     22 jano        20   0 16288  9276  5608 R 100.5  0.1  0:58.57 ├─ python3 cruncher.py
     24 jano        30  10 16288  9420  5756 R 100.5  0.1  0:58.56 ├─ python3 cruncher.py
     26 jano        25   5  215M  209M  5668 S   0.0  1.3  0:00.07 ├─ python3 cache.py
     29 jano        20   0  234M 11804  5784 S   5.4  0.1  0:03.68 ├─ python3 threads.py
     36 jano        20   0  234M 11804  5784 S   2.7  0.1  0:01.28 │  ├─ python3 threads.py
     37 jano        20   0  234M 11804  5784 S   2.0  0.1  0:01.21 │  ├─ python3 threads.py
     38 jano        20   0  234M 11804  5784 S   1.3  0.1  0:01.15 │  └─ python3 threads.py
     31 jano        20   0  5472  1816  1716 S   0.0  0.0  0:00.00 ├─ sleep 9999
F1Help  F2Setup F3SearchF4FilterF5List  F6SortByF7Nice -F8Nice +F9Kill  F10Quit

Sorting in htop

The -s option sets the sort column; htop --sort-key=help lists the names. Interactively, F6 opens a list of columns, M and P sort by memory and CPU as in top, and clicking a column header sorts by it.

htop -s PERCENT_MEM

The process with the most resident memory is now first. The triangle next to the column name marks the sort column and direction; I inverts the order.

$ htop -s PERCENT_MEM

    0[|||||||||||||||||||||||||||||||||||||||||100.0%]   4[||||                                        6.7%]
    1[||||||||                                  16.9%]   5[||||                                        5.4%]
    2[|||||                                      8.7%]   6[|||||                                       9.3%]
    3[|||||||||||||||||||||||||||||||||||||||||100.0%]   7[|||||                                       8.7%]
  Mem[||||||||||||||||||||||||||||||||||||10.9G/15.4G] Tasks: 11, 3 thr, 0 kthr; 3 running
  Swp[||||||||||||||||||||||||||||||||||||1.76G/2.00G] Load average: 2.34 1.75 1.25
                                                       Uptime: 09:35:35

  [Main] [I/O]
    PID USER       PRI  NI  VIRT   RES   SHR S  CPU% MEM%▽  TIME+  Command
     26 jano        25   5  215M  209M  5668 S   0.0  1.3  0:00.07 python3 cache.py
     29 jano        20   0  234M 11804  5784 S   6.0  0.1  0:03.91 python3 threads.py
     36 jano        20   0  234M 11804  5784 S   2.0  0.1  0:01.36 python3 threads.py
     37 jano        20   0  234M 11804  5784 S   2.7  0.1  0:01.28 python3 threads.py
     38 jano        20   0  234M 11804  5784 S   2.0  0.1  0:01.22 python3 threads.py
     24 jano        30  10 16288  9420  5756 R 100.3  0.1  1:02.57 python3 cruncher.py
F1Help  F2Setup F3SearchF4FilterF5Tree  F6SortByF7Nice -F8Nice +F9Kill  F10Quit

Filtering and searching in htop

F4 (or \) filters the list by a string in the command line, and F3 (or /) searches for a process without hiding the others.

htop
F4
cruncher

We pressed F4, typed cruncher, and Enter. Only matching processes remain, and the function bar shows FILTER in capitals as a reminder that a filter is active; pressing F4 and Esc removes it. With a process selected, F9 sends a signal from a menu, F7 and F8 change its nice value, and Space tags several processes to act on all of them at once.

$ htop

    0[|||||||||||||||||||||||||||||||||         70.2%]   4[|||||||||||||||                            30.2%]
    1[||                                         3.4%]   5[|||                                         4.7%]
    2[||                                         2.7%]   6[||                                          2.0%]
    3[|||||||||||||||||||||||||||||||||||||||||100.0%]   7[|||                                         4.7%]
  Mem[||||||||||||||||||||||||||||||||||||10.9G/15.4G] Tasks: 11, 3 thr, 0 kthr; 3 running
  Swp[||||||||||||||||||||||||||||||||||||1.76G/2.00G] Load average: 2.36 1.78 1.26
                                                       Uptime: 09:35:46

  [Main] [I/O]
    PID USER       PRI  NI  VIRT   RES   SHR S  CPU%▽MEM%   TIME+  Command
     24 jano        30  10 16288  9420  5756 R 101.2  0.1  1:13.02 python3 cruncher.py
     22 jano        20   0 16288  9276  5608 R 100.5  0.1  1:13.02 python3 cruncher.py
F1Help  F2Setup F3SearchF4FILTERF5Tree  F6SortByF7Nice -F8Nice +F9Kill  F10Quit

Keys and options of htop

Key or optionAction
F1 / hHelp
F2 / SSetup: meters, columns, colours
F3 / /Search
F4 / \Filter
F5 / t, -tTree view
F6, -sSort column
F7, F8Decrease, increase the nice value
F9 / kSend a signal
F10 / qQuit
u, -uShow one user
p, -pToggle program paths; with -p, show only the given PIDs
H, KHide user threads, kernel threads
SpaceTag a process
-dRefresh delay in tenths of a second

htop saves its settings automatically in ~/.config/htop/htoprc when it exits.

Best practices for top and htop

Source

top(1) manual page, htop website

In this article, we have used top to monitor load, CPU, and memory, read its summary and process columns, sorted and filtered processes, run it in batch mode, and changed priorities, and we have used htop with its meters, tree view, sorting, and filters. See also the ps and kill articles.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.