The Night My Server Crawled to a Stop
It was 11 PM when my production Ubuntu 22.04 server with 4GB RAM started responding like it was running on a Raspberry Pi Zero. Users were complaining, response times spiked, and I had absolutely no idea what was eating the resources. I SSH’d in and typed top — which gave me a wall of numbers that told me almost nothing useful under pressure.
That night, I discovered three tools that I now consider essential on every Linux server I manage: htop, iotop, and nethogs. Each one focuses on a specific resource — CPU/memory, disk I/O, and network — and together they answer the three questions that matter most when a server slows down: what’s burning CPU, what’s hammering the disk, and what’s eating the bandwidth.
Understanding What Each Tool Does
htop — The Better top
If you’ve used top before, you’ll appreciate htop immediately. It’s an interactive process viewer with a color-coded display, mouse support, and controls that are actually intuitive. You can sort processes, kill them, and filter by user — all without memorizing cryptic key combinations.
Key metrics it shows you:
- Per-CPU core usage (not just an average)
- Memory and swap usage as visual bars
- Load averages over 1, 5, and 15 minutes
- Process tree view (which process spawned which)
iotop — Catching the Disk Hog
iotop does for disk what htop does for CPU. It shows you per-process read/write activity in real time. This is the tool you reach for when your disk I/O is maxed out but htop shows CPU is mostly idle — a common and confusing scenario.
nethogs — Per-Process Network Usage
Standard tools like iftop or nload show total bandwidth per interface. nethogs goes one level deeper: it attributes that bandwidth to individual processes. When something is hammering your upload at 50 Mbps, nethogs tells you exactly which PID is responsible.
Installing All Three
On Debian/Ubuntu:
sudo apt update
sudo apt install htop iotop nethogs -y
On RHEL/AlmaLinux/Fedora:
sudo dnf install htop iotop nethogs -y
Hands-On: Using htop Effectively
Just run:
htop
The first thing you’ll notice is the CPU bars at the top — one per core. On my 4-core server, when one bar is pegged at 100% while others are idle, I know immediately that some single-threaded process is the culprit.
Useful keyboard shortcuts inside htop:
- F6 — Sort by any column (CPU%, MEM%, TIME, etc.)
- F4 — Filter processes by name
- F5 — Toggle tree view (see parent-child relationships)
- F9 — Send a signal (kill, SIGTERM, etc.) to selected process
- Space — Tag a process (then act on multiple at once)
Worth doing on every new server: press F2 → Display Options → check “Show custom thread names”. PHP-FPM workers and Python threads become much easier to spot.
Running htop for a Specific User
htop -u www-data
Perfect for cutting through the clutter — you’ll only see www-data’s processes, not the dozens of system daemons running in the background.
Hands-On: Diagnosing Disk I/O with iotop
iotop needs root. Run it as:
sudo iotop
By default, it shows all processes, including those with zero I/O. That gets noisy fast. Use these flags instead:
# Only show processes actively doing I/O
sudo iotop -o
# Non-interactive snapshot (useful for scripts)
sudo iotop -o -b -n 3
The -b flag runs in batch mode (no interactive UI), and -n 3 takes 3 snapshots then exits. This is great for capturing I/O spikes in a cron job or log file.
What the Columns Mean
- DISK READ — How much data the process is reading from disk per second
- DISK WRITE — How much it’s writing
- SWAPIN — Percentage of time waiting for data to be swapped in from swap space (if this is high, you’re in trouble)
- IO> — Percentage of time the process spent doing I/O
On my production server, that’s when it clicked: a nightly MySQL backup was running mysqldump and hammering the disk at 80MB/s — every other process queued up waiting. The fix was straightforward. Add --single-transaction to avoid table locks, and pipe through gzip to compress on the fly. Write volume dropped by around 70%, and the server stopped crawling.
Hands-On: Tracking Network Usage Per Process with nethogs
sudo nethogs
Or specify the interface if you have multiple NICs:
sudo nethogs eth0
sudo nethogs ens3 # common on cloud VMs
nethogs updates every second by default. You’ll see something like:
NetHogs version 0.8.7
PID USER PROGRAM DEV SENT RECEIVED
1847 www-data /usr/sbin/apache2 ens3 4.382 12.543 KB/sec
2341 ubuntu scp ens3 0.000 45.210 KB/sec
. unknown unknown TCP ens3 0.083 0.024 KB/sec
TOTAL 4.465 57.777 KB/sec
That scp process is pulling 45 KB/s — likely a backup or file transfer in progress. Knowing it’s PID 2341 means you can check who’s running it with:
ps -p 2341 -o pid,user,cmd
Keyboard Controls in nethogs
- m — Toggle between KB/s, KB, and B display modes
- r — Sort by received traffic
- s — Sort by sent traffic
- q — Quit
Combining All Three: A Real Troubleshooting Flow
Here’s how I actually use these tools together when something goes wrong:
- Start with htop — Is CPU or memory the bottleneck? If load average is 4× your core count, CPU is saturated. If swap is in use, memory is the issue.
- If CPU looks okay, switch to iotop — Run
sudo iotop -oand see if any process has high IO% or SWAPIN%. Disk I/O saturation often masquerades as general slowness. - If both look fine, check nethogs — Something might be consuming outbound or inbound bandwidth, causing application timeouts or API delays.
This three-step flow has helped me diagnose issues ranging from a runaway log rotation script (disk I/O) to a compromised server pushing data out at 100 Mbps (network — caught by nethogs in under 30 seconds).
Quick Reference Card
# htop — interactive CPU/memory monitor
htop
htop -u username # filter by user
htop -p 1234,5678 # watch specific PIDs
# iotop — disk I/O per process
sudo iotop -o # only active processes
sudo iotop -o -b -n 5 # 5 batch snapshots, good for logging
# nethogs — network usage per process
sudo nethogs # auto-detect interface
sudo nethogs eth0 ens3 # monitor multiple interfaces
Make Them Available System-Wide
If you’re managing servers where multiple team members SSH in, it’s worth adding a small alias so everyone can run nethogs without remembering the sudo requirement:
# Add to /etc/bash.bashrc or each user's ~/.bashrc
alias nethogs='sudo nethogs'
alias iotop='sudo iotop -o'
Three Tools, One Habit
Between htop, iotop, and nethogs, you have per-process visibility into every major resource on your server. CPU, memory, disk, and network — covered. No guessing.
Next time something feels slow, resist the urge to immediately restart services or reboot. Open these tools first. Nine times out of ten, the answer is right there in the output — and you’ll find it in minutes instead of hours.

