32blogby StudioMitsu

htop and btop Guide: Master Linux Process Monitoring

Learn to monitor and manage Linux processes with htop and btop. Covers installation, keyboard shortcuts, process states, kill signals, nice priorities, and real-world troubleshooting patterns.

16 min read
On this page

htop and btop are interactive process monitors that replace the aging top command with color-coded dashboards, mouse support, and built-in process management. If you've ever stared at top trying to figure out which process is eating your CPU, these tools make it obvious in seconds.

In short: use htop for a fast, lightweight process viewer that works everywhere, and btop when you want a full system dashboard with CPU graphs, network stats, and disk I/O in one screen. Both let you kill processes, change priorities, and filter by name — all without leaving the terminal.

Why top Isn't Enough

The top command ships with every Linux system, and for quick checks it works. But after using it for years on production servers, I hit the same frustrations over and over:

  • No mouse support — you navigate entirely with cryptic single-key commands
  • No horizontal scrolling — long command lines get truncated with no way to see them
  • Ugly defaults — monochrome output with no visual distinction between CPU, memory, and swap
  • Killing a process requires typing the PID — you can't just select and kill

Here's what top actually shows you:

bash
top - 14:32:01 up 47 days,  3:12,  2 users,  load average: 2.31, 1.87, 1.45
Tasks: 312 total,   1 running, 308 sleeping,   0 stopped,   3 zombie
%Cpu(s): 15.2 us,  3.1 sy,  0.0 ni, 80.4 id,  0.8 wa,  0.0 hi,  0.5 si
MiB Mem :  15921.4 total,   1243.2 free,   8934.1 used,   5744.1 buff/cache
MiB Swap:   4096.0 total,   3891.2 free,    204.8 used.   6192.0 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 1847 www-data  20   0 1245832 234112  18432 S  45.2  1.4  12:34.56 node
 2103 postgres  20   0  987264 456320  32768 S  23.1  2.8   8:21.03 postgres

That's a wall of numbers. Now compare the same information in htop — you get color-coded CPU bars per core, memory gauges, and a scrollable process list where you can click to select. The information density is the same, but the cognitive load drops dramatically.

htop: The Interactive Upgrade

htop has been around since 2004 and is now maintained at htop-dev/htop on GitHub. Version 3.4.1 (April 2025) added GPU monitoring meters and improved Unicode handling.

Installation

bash
# Debian / Ubuntu
sudo apt install htop

# Fedora / RHEL
sudo dnf install htop

# Arch Linux
sudo pacman -S htop

# macOS
brew install htop

On most distributions, htop is already in the default repositories. No PPAs or third-party repos needed.

What You See When You Launch htop

Run htop and you get three sections:

  1. Header — CPU bars (one per core), memory bar, swap bar, load average, uptime, and task count
  2. Process list — sortable, scrollable table with PID, user, CPU%, MEM%, command, and more
  3. Footer — function key shortcuts (F1–F10)

The CPU bars use colors to show what's consuming each core:

ColorMeaning
GreenUser-space processes (your applications)
RedKernel-space processes (system calls, I/O)
BlueLow-priority (nice) processes
Teal/CyanIRQ handling time

When I set up a new VPS for 32blog, the first thing I do after SSH is run htop to check the baseline. A fresh Ubuntu server should show CPU bars nearly empty and memory around 200–400 MB. If memory is already at 60% before deploying anything, something is wrong.

Essential Keyboard Shortcuts

These are the shortcuts I use daily:

KeyAction
F2 or SSetup — configure meters, columns, color scheme
F3 or /Search — find a process by name
F4 or \Filter — show only matching processes
F5 or tTree view — show parent-child process hierarchy
F6 or < >Sort — change sort column
F9 or kKill — send signal to selected process
F10 or qQuit
SpaceTag a process (for batch operations)
UUntag all
uShow only processes from a specific user
HToggle user threads
KToggle kernel threads
pToggle program path / basename

The tree view (F5) is incredibly useful for debugging. When a Node.js app spawns child processes, the tree shows you exactly which parent owns which workers. I once spent 20 minutes with ps aux | grep node trying to untangle a process hierarchy that htop's tree view made obvious in seconds.

Customizing the Header

Press F2 to enter the setup screen. You can add meters like:

  • CPU average — single bar for all cores combined
  • Disk I/O — read/write throughput
  • Network I/O — bytes in/out (htop 3.4+)
  • System load — 1/5/15 minute averages
  • Hostname and clock — useful when you have multiple SSH sessions open

I configure my servers with CPU (per-core) on the left, and memory + swap + load on the right. The config is saved to ~/.config/htop/htoprc, so you can copy it across machines with scp.

Filtering and Sorting

Sorting by memory to find leaks:

bash
# Launch htop sorted by memory
htop --sort-key=PERCENT_MEM

Inside htop, press F6 and select PERCENT_MEM to sort by memory usage. The biggest consumers float to the top. This is how I spotted a PostgreSQL connection leak on a staging server — 47 idle connections each holding 30 MB of resident memory.

To filter by a specific process name, press F4 and type node or postgres. Unlike search (F3), filtering hides all non-matching processes, giving you a focused view.

btop: The Full Dashboard

btop is the C++ successor to bashtop and bpytop. Where htop focuses on the process list, btop gives you a full system overview — CPU graphs over time, network throughput, disk activity, and battery status in a single terminal window. Version 1.4.6 (December 2025) added process renice support and improved AMD CPU name trimming.

Installation

bash
# Debian / Ubuntu (22.04+)
sudo apt install btop

# Fedora
sudo dnf install btop

# Arch Linux
sudo pacman -S btop

# macOS
brew install btop

# Snap (any distro)
sudo snap install btop

The btop Interface

btop divides the screen into boxes:

  • CPU box — per-core usage bars + a rolling graph showing usage over time
  • Memory box — RAM and swap usage with graphs
  • Network box — upload/download speed in real-time
  • Disk box — read/write throughput per mounted filesystem
  • Process box — sortable, filterable process list (similar to htop)

The rolling CPU graph is what sold me on btop. When debugging a cron job that causes periodic CPU spikes, htop shows you the current snapshot. btop shows you the pattern over the last few minutes, making it obvious that the spike happens every 60 seconds.

Key Shortcuts

KeyAction
Esc / mMain menu
fFilter processes
tTree view
kKill selected process
rRenice selected process
+ / -Increase/decrease update interval (100ms steps)
14Toggle box visibility (CPU, memory, network, disk)
TabCycle focus between boxes
eToggle per-core graphs

Configuration

btop's config lives at ~/.config/btop/btop.conf. You can also press Esc → Options to configure via the built-in menu:

ini
# ~/.config/btop/btop.conf (key settings)
color_theme = "Default"
theme_background = False    # transparent background for tiling WM users
update_ms = 2000            # refresh every 2 seconds (default: 2000)
proc_sorting = "cpu lazy"   # sort by CPU, but don't re-sort every frame
shown_boxes = "cpu mem net proc"  # show these boxes

I set theme_background = False on my WSL2 setup so btop's background matches my Windows Terminal theme. Small touch, but it looks clean.

htop vs btop: When to Use Which

Criteriahtopbtop
Startup timeInstant~1 second
Resource usage~5 MB RAM~20 MB RAM
Network / Disk I/OHeader meters only (3.4+)Dedicated graph boxes
Historical graphsNoYes (rolling CPU/network/disk)
Mouse supportYesYes
Tree viewYesYes
GPU monitoringYes (3.4+)Yes
Available onAlmost everywhereRequires C++20 capable compiler

My rule of thumb: htop on servers (lighter, faster, available everywhere), btop on my local workstation (more data, prettier). On a 512 MB VPS, every megabyte counts — htop wins. On my dev machine with 32 GB RAM, btop's graphs are worth the extra memory.

Process Management: Kill, Nice, and Signals

Both htop and btop let you manage processes directly from the UI, but understanding what happens behind the scenes makes you more effective.

Signals

When you press F9 (kill) in htop, you're actually sending a signal to the process. The most important ones:

SignalNumberEffect
SIGTERM15Polite request to terminate. The process can catch this and clean up
SIGKILL9Forced termination. The kernel kills the process immediately — no cleanup
SIGHUP1Hang up. Many daemons reload config when they receive this
SIGSTOP19Pause the process (like Ctrl+Z). Resume with SIGCONT
SIGCONT18Resume a stopped process
SIGINT2Interrupt — what happens when you press Ctrl+C

Always try SIGTERM first. SIGKILL should be a last resort because the process can't clean up — temp files won't be deleted, database transactions won't be rolled back, and child processes may become orphans.

From the command line:

bash
# Graceful shutdown
kill 1847

# Force kill (only when SIGTERM doesn't work after a few seconds)
kill -9 1847

# Kill by name
pkill -f "node server.js"

# Kill all processes by a user
pkill -u www-data

I learned the hard way not to kill -9 PostgreSQL. The database came back up fine, but it had to replay the WAL log, which took 4 minutes on a busy server. SIGTERM lets Postgres finish active queries and flush buffers first.

Nice and Renice

Every process has a nice value from -20 (highest priority) to 19 (lowest priority). The default is 0. Higher nice values mean the process is "nicer" to other processes — it yields CPU time.

bash
# Start a CPU-heavy task with low priority
nice -n 10 ffmpeg -i input.mp4 -c:v libx264 output.mp4

# Change priority of a running process
renice 15 -p 1847

# Set highest priority (requires root)
sudo renice -20 -p 1847

In btop, press r on a selected process to renice it. In htop, you can use F7 (lower nice = higher priority) and F8 (higher nice = lower priority).

Practical Patterns

Find and kill a process eating CPU:

bash
# In htop: press F6, sort by CPU%, select the process, press F9, choose SIGTERM

# From command line:
ps aux --sort=-%cpu | head -5
kill $(pgrep -f "runaway-script")

Kill zombie processes:

Zombies can't be killed directly — they're already dead. You need to kill the parent process:

bash
# Find zombie processes
ps aux | awk '$8 ~ /Z/ {print $2, $11}'

# Find the parent PID
ps -o ppid= -p <zombie_pid>

# Kill the parent (or send SIGCHLD to nudge it)
kill -SIGCHLD <parent_pid>

Reading Process States Like a Pro

In htop's S column (or btop's State column), each process shows a single letter indicating its state. Knowing what these mean is essential for debugging:

StateSymbolMeaning
RunningRActively using CPU or waiting in the run queue
SleepingSWaiting for an event (I/O, timer, signal). Most processes are here
Disk SleepDUninterruptible sleep — waiting for disk I/O. Cannot be killed
StoppedTPaused by SIGSTOP or Ctrl+Z
ZombieZProcess exited but parent hasn't read its exit status yet

What to Worry About

Too many D (disk sleep) processes — this usually means your disk is overwhelmed. Check I/O wait in the CPU header (the wa value in top, or the red portion in htop if configured). If wa is above 20%, your storage is the bottleneck. On cloud VPSes, this often means you've exhausted your burst IOPS.

Zombie processes accumulating — a few zombies are normal and harmless (they consume almost no resources, just a slot in the process table). But if the count keeps growing, the parent process has a bug — it's not calling wait() on its children. Check which parent owns them and restart it.

Load average higher than CPU cores — if your system has 4 cores and the 1-minute load average is 12, processes are queuing up waiting for CPU time. Use htop's tree view to find which process tree is causing the load.

bash
# Quick check: how many cores vs load average?
nproc              # number of CPU cores
uptime             # load averages at the end

# If load >> nproc, find the culprits:
htop --sort-key=PERCENT_CPU

One common mistake: high load average doesn't always mean high CPU usage. Processes in D state (disk sleep) also count toward load. If CPU is low but load is high, your bottleneck is storage, not compute.

Real-World Debugging with htop

Here's a scenario I hit on 32blog's VPS. The Next.js build was taking 3× longer than usual:

  1. Opened htop, sorted by CPU — nothing unusual, CPU was at 40%
  2. Checked load average — it was 8.2 on a 2-core machine
  3. Pressed F5 for tree view — saw 6 node processes (Next.js build workers)
  4. Looked at the S column — most were in D state (disk sleep)
  5. Diagnosis: the VPS had exhausted its burst IOPS. The build was I/O-bound, not CPU-bound

The fix was simple: upgrade to an SSD-backed VPS tier. But without htop showing me the process states at a glance, I would've wasted time trying to optimize the build config.

FAQ

Is htop better than top?

For interactive use, yes. htop adds color-coded CPU bars, mouse support, tree view, and in-place process management. top's advantage is that it's pre-installed everywhere, so it's useful on minimal containers or rescue shells where you can't install packages.

Can I use btop over SSH?

Yes, but your terminal needs to support the extended character set btop uses for graphs. Most modern terminals (Windows Terminal, iTerm2, Alacritty, kitty) work fine. If graphs render as broken characters, try setting TERM=xterm-256color or fall back to htop.

How do I kill a process that won't die with SIGTERM?

Wait a few seconds (the process might be cleaning up), then use kill -9 <PID> or press F9 in htop and select signal 9 (SIGKILL). If even SIGKILL doesn't work, the process is likely stuck in uninterruptible sleep (D state) waiting for a kernel operation — usually a dead NFS mount or stuck disk. In that case, you may need to reboot.

What's the difference between VIRT, RES, and SHR in htop?

VIRT is the total virtual memory the process has mapped — includes shared libraries, memory-mapped files, and allocated but unused memory. RES (resident) is what's actually in RAM right now. SHR is the portion of RES shared with other processes (mostly shared libraries). Focus on RES — that's the real memory footprint.

Do htop and btop work on macOS?

Yes. Install via Homebrew (brew install htop btop). Some Linux-specific features like per-core frequency or cgroup information won't be available, but the core monitoring and process management work the same.

How do I make htop start with my preferred sort order?

Use command-line flags: htop --sort-key=PERCENT_MEM to sort by memory. Or configure it in the setup screen (F2) and it saves to ~/.config/htop/htoprc.

Can I monitor a Docker container's processes with htop?

Yes. Run htop on the host and filter (F4) by the container's main process name. Or run htop inside the container with docker exec -it <container> htop — this shows only the container's processes, making it easier to focus.

How often do htop and btop refresh?

htop defaults to every 1.5 seconds, btop to every 2 seconds. Both are configurable — in htop via the setup screen, in btop with +/- keys or the update_ms config option.

Wrapping Up

top gets the job done in a pinch, but htop and btop turn process monitoring from a chore into something you can actually reason about. htop is my go-to on servers — it's everywhere, lightweight, and the tree view alone is worth the install. btop lives on my local machine where the CPU graphs and network monitoring give me a complete picture without opening five different tools.

The real value isn't in the pretty colors. It's in the workflow: see a spike, filter to the process, check its state, send a signal — all without leaving the terminal or memorizing PIDs. Once you build that muscle memory, you'll wonder how you ever managed processes any other way.

Next step: if you're managing background tasks that run on a schedule, check out the cron and systemd timer guide. And if you're writing scripts that spawn child processes, the shell scripting guide covers proper signal handling and cleanup traps.