Short answer: htop is an interactive process viewer: the top of the screen shows one bar per CPU core, memory, swap, the load average and uptime, and below it every process, refreshed live. Press P or M to sort by CPU or memory, F4 to filter by name, F5 for a tree view, F9 to kill the highlighted process and q to quit. top does the same job, is installed on almost every Linux system, and shares most of the single-letter keys.
htop # start it
htop -u www-data # only one user's processes
htop -t # start in tree view
top # the built-in alternative, no install neededThe keys, columns and colours below were checked against htop 3.2.2 and top from procps-ng 4.0.2 on Debian 12; the colour legend comes straight from htop’s own help screen (F1). Other versions move a menu item here and there; the keys have been stable for years.
Cheat sheet: htop keys and the top equivalent
| Task | htop | top |
|---|---|---|
| Sort by CPU | P | P |
| Sort by memory | M | M |
| Sort by CPU time used | T | T |
| Pick any sort column | F6, or < > | < > to move it |
| Reverse the sort order | I | R |
| Search for a process | F3 or / | L, then & for next |
| Filter to matching processes | F4 or \ | o, e.g. COMMAND=nginx |
| Tree view | F5 or t | V |
| One user only | u | u |
| Kill (send a signal) | F9 or k | k |
| Change priority (nice) | F7 / F8 | r |
| Show or hide threads | H | H |
| One line per CPU core | Shown by default | 1 |
| Full command line | Shown by default (p toggles the path) | c |
| Help | F1 or h | h or ? |
| Save the layout | Automatic on exit | W |
| Quit | F10 or q | q |
Installing htop
sudo apt install htopsudo dnf install epel-release
sudo dnf install htopOn Rocky and AlmaLinux htop lives in EPEL, not the base repositories, which is why the first line is needed. Ubuntu Server images usually have it already; a minimal Debian install does not. You do not need root to run it, but as a normal user you cannot kill or renice other users’ processes, and some columns stay empty for processes that are not yours.
Reading the header: CPU bars, memory, swap and load
This is the default two-column header on a 4 vCPU server (the layout is htop 3.2.2’s; the numbers are an example):
0[|||||||| 21.3%] 2[|||||||||||||| 38.7%]
1[||||| 12.0%] 3[||| 6.1%]
Mem[|||||||||| 2.41G/7.75G] Tasks: 41, 112 thr, 87 kthr; 2 running
Swp[| 112M/2.00G] Load average: 0.84 0.61 0.55
Uptime: 12 days, 03:14:07CPU bars and what the colours mean
One bar per core, numbered from 0. On a VPS each bar is a vCPU, so a 4 vCPU plan shows four. The percentage is how busy that core was during the last refresh. The colours split that time by type, and the legend changes with one setting: F2 Setup, Display options, Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest). It is off by default.
| Colour | Default view | With Detailed CPU time |
|---|---|---|
| Blue | Low-priority (niced) processes | Low-priority (niced) processes |
| Green | Normal user processes | Normal user processes |
| Red | Kernel, interrupts included | Kernel (system calls) only |
| Yellow | Not used | Hardware interrupts (irq) |
| Magenta | Not used | Software interrupts (soft-irq) |
| Cyan | Virtualisation (labelled guest) | Steal, and guest |
| Dark grey | Not used | Waiting on disk (io-wait) |
A bar that is mostly green means your applications are doing the work. Mostly red means the kernel is busy on their behalf: heavy network traffic, lots of small disk operations, or a storm of system calls. For the exact numbers instead of colours, add a CPU meter in Text mode in the same Setup screen (Meters). With detailed CPU time on, it prints a line like this:
Avg: 1.8% sy: 0.7% ni: 0.0% hi: 0.0% si: 0.1% st: 0.0% gu: 0.0% wa: 0.0%Those are the same fields top prints on its %Cpu(s) line, explained below. The one that matters most on a VPS is st, steal time.
Memory and swap
The Mem bar is green for memory programs are using, blue for buffers, magenta for shared memory and yellow for the page cache. The figure after it is used memory out of the total, and it leaves the cache out on purpose: the kernel fills spare RAM with cached files and hands it back the moment a program needs it. A bar that looks full but is mostly yellow is a healthy server, not a full one. htop counts “used” slightly differently from free -h and top, so expect the figures to differ by a few hundred megabytes.
The Swp bar is red for swap in use. Some swap in use on a server that is not slow is normal (idle pages get moved out); swap that keeps climbing while the server crawls means it is short of RAM. 0K/0K means no swap is configured at all, which adding a swap file fixes in a couple of minutes.
Tasks, load average and uptime
- Tasks: 41, 112 thr, 87 kthr; 2 running means 41 processes, 112 user threads, 87 kernel threads, and 2 tasks on a CPU right now.
- Load average is three numbers: the average count of tasks running or waiting for a CPU over the last 1, 5 and 15 minutes. On Linux it also counts tasks stuck waiting on disk. Compare it with the number of CPU bars: a load of 4.0 on 4 vCPUs is fully busy, a load of 8.0 on 4 vCPUs means work is queuing. A high load with idle-looking CPU bars points at storage, not the processor.
- Uptime is the time since the last boot. htop adds
(!)once it passes 100 days, a gentle hint: a server that has not rebooted in that long is often still running an old kernel after updates.
What the process columns mean
PID USER PRI NI VIRT RES SHR S CPU%▽MEM% TIME+ Command
1187 www-data 20 0 312M 61204 38120 R 38.2 0.8 4:12.55 php-fpm: pool www
812 mysql 20 0 2412M 447M 34560 S 12.6 5.6 52:10.03 /usr/sbin/mariadbd
774 www-data 20 0 58712 12844 7520 S 1.3 0.2 0:44.18 nginx: worker process
1 root 20 0 164M 9964 6420 S 0.0 0.1 0:41.02 /sbin/init| Column | Meaning |
|---|---|
| PID | Process ID; for a thread, the thread's own ID |
| USER | Owner of the process |
| PRI, NI | Kernel priority and nice value (-20 is most favoured, 19 least) |
| VIRT | Virtual memory mapped: reserved, not necessarily used. Often huge and mostly harmless |
| RES | Resident memory: physical RAM the process is actually using, in KiB unless suffixed |
| SHR | The part of RES that is shared with other processes (libraries, shared memory) |
| S | State: R running, S sleeping, D waiting on disk, Z zombie, T stopped, I idle |
| CPU% | Share of one core during the last refresh; a multi-threaded process can show 250% |
| MEM% | RES as a share of total RAM |
| TIME+ | CPU time used since start: minutes:seconds.hundredths, or 1h48:54 past an hour |
| Command | The full command line |
The small triangle after CPU% marks the column the list is sorted by. Two details catch people out:
- The same program listed many times. Those rows are threads, which htop shows by default; their command is printed in green. Press
Hto hide user threads, andKto toggle kernel threads (hidden by default). - A program name in red. According to the htop man page, the binary that process was started from has been replaced or deleted on disk since it started. After an
apt upgradethat means it is still running the old version until you restart it. Yellow means one of its libraries was replaced.
F2, Columns, adds more. Two worth knowing: OOM (the score the out-of-memory killer would pick a victim by) and DISK R/W (per-process disk throughput). For disk I/O there is also a ready-made second tab: press Tab to switch from Main to I/O. Run htop with sudo for that tab to fill in for other users’ processes.
For what each state letter means in detail, and why a process stuck in D ignores even kill -9, see ps aux explained, which uses the same columns.
Sorting: by CPU, memory or time
P, M and T sort by CPU, memory and accumulated CPU time, the same letters as in top; N sorts by PID. F6 opens a list of every column to sort by, and I inverts the order. To start htop already sorted, give the column name from htop --sort-key help:
htop -s PERCENT_MEM # biggest memory users first
htop -s TIME # longest-running CPU consumers firstSorting by CPU shows what is busy now, measured over the last refresh interval (1.5 seconds by default, -d 20 for 2 seconds, in tenths). Sorting by TIME+ shows what has used the most CPU since it started, which catches a process that spikes every few minutes and looks idle whenever you happen to look.
Search and filter: F3 and F4
F3 (or /) searches: the highlight jumps to the first process whose command line contains what you type, and F3 again moves to the next match. The rest of the list stays visible. F4 (or \) filters: only matching processes remain, which is the one to use when you want to watch a single service. The filter ignores case and matches plain text, not regular expressions; separate several terms with | to match any of them. To clear it, press F4 again and then Esc.
htop -F "nginx|php-fpm" # start filtered to two programs
htop -p 812,1187 # only these PIDs
htop -u mysql # only one user's processes (u inside htop)Tree view: F5
F5 (or t) arranges processes by parent, so you can see that the nine php-fpm workers all hang off one master, or which shell started a runaway script. - and + collapse and expand the highlighted branch, * toggles all of them. Sort keys keep working in tree view: P or M reorders the processes within each branch and the tree stays (checked in htop 3.2.2; the man page still describes the htop 2 behaviour, where sorting left tree view, and Display options can bring that back). The same picture as plain text, for pasting into a ticket, is ps -ef --forest or pstree -p.
Killing and renicing from htop
Highlight the process and press F9 (or k). htop opens a list of signals with 15 SIGTERM preselected; Enter sends it. That is the polite request to exit, and it is the right first choice. Pick 9 SIGKILL only if the process ignores SIGTERM. To act on several at once, tag each with Space (or c to tag a process together with its children), then press F9: the signal goes to every tagged process. U clears the tags.
F8 lowers the highlighted process’s priority (raises its nice value) and F7 raises it; only root can raise priority. A backup job or a compiler at nice 19 still gets all the CPU nobody else wants, but yields immediately when a web request needs a core. htop can be run with --readonly when you only want to look and would rather not kill anything by accident.
The top command: same job, already installed
top is part of procps-ng, so it is there on practically every Linux system, including the minimal images where htop is not. It shows the same information in a plainer layout:
top - 14:02:51 up 12 days, 3:14, 1 user, load average: 0.84, 0.61, 0.55
Tasks: 131 total, 2 running, 129 sleeping, 0 stopped, 0 zombie
%Cpu(s): 15.9 us, 3.1 sy, 0.0 ni, 80.2 id, 0.4 wa, 0.0 hi, 0.2 si, 0.2 st
MiB Mem : 7936.0 total, 912.4 free, 2468.1 used, 4555.5 buff/cache
MiB Swap: 2048.0 total, 1936.0 free, 112.0 used. 5467.9 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1187 www-data 20 0 319488 61204 38120 R 38.2 0.8 4:12.55 php-fpm8.2
812 mysql 20 0 2469888 457812 34560 S 12.6 5.6 52:10.03 mariadbd
774 www-data 20 0 58712 12844 7520 S 1.3 0.2 0:44.18 nginx| Field | Meaning |
|---|---|
us | Normal user processes (htop's green) |
sy | Kernel (htop's red) |
ni | Niced, low-priority user processes (htop's blue) |
id | Idle |
wa | Idle while waiting for disk I/O |
hi / si | Hardware and software interrupts |
st | Stolen from this VM by the hypervisor |
Line 4 is physical memory and avail Mem at the end of line 5 is the number to watch: how much RAM new programs could get without swapping. Press 1 for one line per core, c to show full command lines, and W to save the layout so it comes back next time. Where top beats htop is scripting: batch mode prints one snapshot as plain text, which htop cannot do.
top -b -n 1 | head -n 15 # one snapshot, for a log or a ticket
top -b -n 1 -o %MEM | head -n 15 # sorted by memory instead
top -b -n 3 -d 5 > top.log # three snapshots, five seconds apartRunning out of CPU and not sure where to go from the top line? VPS high CPU usage walks through reading us, sy, wa and st and what to do about each one.
Steal time (st) on a VPS
Steal is time your virtual machine had work ready for a vCPU, but the hypervisor was running something else on that physical core, usually another customer’s VM. Inside the VM it looks like a slow CPU: everything takes longer and nothing in the process list explains it. Three ways to see it:
top # the st value on the %Cpu(s) line; press 1 for each vCPU
vmstat 1 10 # the st column, once a second for ten seconds
# htop: F2, Display options, tick "Detailed CPU time", then read the cyan
# part of each bar, or add a CPU meter in Text mode and read st:A few percent now and then is normal on any shared platform. Steal that stays above roughly 5 to 10% while your own us is modest means the host is contended, and nothing you run inside the VM changes that: renicing, killing processes or tuning the application does not give the stolen time back. Note it down with timestamps (vmstat 1 60 > steal.log) and raise it with your provider.
Steal belongs to virtualisation. On a VPS, a vCore is scheduled by the hypervisor, not reserved for you. VMHeaven’s Hi-CPU KVM plans put fewer vCores on each plan for work that leans on one or two cores, but they are still shared VPS cores. On a dedicated server there is no hypervisor between the operating system and the CPU, so st is always zero there.
Saving the layout, and running htop over SSH
Everything you change in F2 Setup (meters, columns, colours, detailed CPU time) is written to ~/.config/htop/htoprc when you quit, per user. The file is overwritten by htop itself, so change settings in the Setup screen rather than by hand. Over SSH, htop works in any terminal; if the function keys do nothing (common in some web consoles and on macOS laptops), every one of them has a letter, listed in the cheat sheet above. If the colours look wrong, htop -C starts it in monochrome.
When htop is not the right tool
- In a script or a cron job. htop is interactive only. Use
top -b -n 1orps -eo pid,user,%cpu,%mem,comm --sort=-%cpu, as shown in ps aux explained. - A process that was killed for memory. By the time you open htop it is gone; the kernel log has the record, as OOM-killed processes explains.
- Slow disk rather than busy CPU. A high load average with idle bars and a high
wais a storage question; testing disk speed shows how to measure what the disk actually delivers.
Frequently asked
What do the colours in htop's CPU bars mean?
In htop's default colour scheme, blue is low-priority (niced) processes, green is normal user processes, red is the kernel and cyan is virtualisation time. With Detailed CPU time switched on under F2 Setup, Display options, yellow adds hardware interrupts, magenta software interrupts, cyan becomes steal and guest time, and dark grey is time spent waiting on disk.
Why does htop show the same program many times?
Those extra rows are the program's threads, which htop lists by default and prints in green. Press H to hide user threads, or K to show or hide kernel threads; htop saves the setting when you quit.
What is the difference between htop and top?
Both show live CPU, memory and process data. top ships with procps-ng, is on almost every Linux system and has a batch mode (top -b -n 1) for scripts. htop is a separate package with coloured bars, scrolling, mouse support, a tree view on F5 and a kill menu that needs no PID. Most single-letter keys, such as P, M and k, work the same in both.
How do I see steal time in htop?
Open F2 Setup, Display options, and tick Detailed CPU time; steal then shows as a cyan part of each CPU bar, and a CPU meter set to Text mode prints it as st. Outside htop, the st value on top's %Cpu(s) line or the st column of vmstat 1 shows the same figure. Steal that stays above a few percent on a VPS means the host is contended.