Most developers run htop to identify a slow build process, closing the utility without analyzing the displayed resource metrics. Both htop and Glances surface system details that allow developers to diagnose slow runtime processes, memory-leaking container environments, and CPU-bound thread tasks.
Reading htop: Interpreting Console Visualizers
htop is an interactive process viewer that improves on the legacy Unix top command. It displays color-coded bars, process sorting, and process tree hierarchies.
Installation
# Ubuntu/Debian
sudo apt install htop
# macOS via Homebrew
brew install htop
# Arch Linux
sudo pacman -S htop
# Launch htop
htop
The CPU Utilization Bar Colors
The colored bars at the top of htop represent each CPU core’s active utilization, broken down by type:
- Blue: Low-priority (nice) processes.
- Green: Normal user-space processes.
- Red: Kernel and system-space processes.
- Yellow: Hardware interrupts (IRQ) and soft IRQs.
- Cyan: Steal time (VM hypervisor overhead inside virtualized instances).
When you run a CPU-intensive compilation (such as a TypeScript build or Webpack compilation), the core bars spike to green and red. If you see only one core reach 100% while others remain idle, the build script is running in single-threaded mode, indicating that upgrading the system’s core count will not improve build speeds.
Memory, Cache, and Swap Columns
The system memory bar uses distinct colors to represent allocation states:
- Green: Resident Set Size (RSS) memory, representing physical RAM allocated by processes.
- Blue: Buffer memory, representing memory pages reserved by the kernel for disk I/O staging.
- Yellow: Cache memory, representing page caches for file reads. The kernel reclaims this memory instantly when a user process requests physical RAM.
Linux aggressively uses available memory for disk caching to accelerate subsequent file reads. This cache growth is normal behavior. When a development environment (like WSL2) appears to consume significant memory, it is often due to page cache allocation.
The Swap space bar indicates memory pressure. If the system actively swaps memory pages to disk, it produces significant I/O latency, causing database and web server response times to degrade.
Load Averages
The three load average metrics display system pressure over the past 1, 5, and 15 minutes:
Load average: 3.24 2.18 1.87
Load average measures the average number of threads that are either executing or waiting in the CPU queue. On an 8-core CPU:
- A load of 8.0 represents 100% utilization.
- A load of 16.0 represents 200% utilization, meaning threads must wait in queue for CPU cycles.
- A load of 0.5 represents 6.25% utilization, indicating the system is mostly idle.
The trend across the three values reveals system recovery status:
- If the 1-minute average exceeds the 15-minute average, system load is increasing.
- If the 1-minute average is less than the 15-minute average, the load spike has passed and the system is recovering.
htop Keyboard Shortcuts
F2 / S Open setup menu to configure columns and colors
F3 / / Search for processes matching a string pattern
F4 Filter active processes by name
F5 Toggle tree view hierarchy (parent-child relationships)
F6 Change sort column (CPU%, MEM%, PID, TIME)
F9 Send kill signals (SIGTERM, SIGKILL) to selected PID
H Toggle display of user threads
K Kill selected process
Glances: Aggregated Full-Stack Monitoring
Glances aggregates metrics for CPU, memory, disk I/O, network interfaces, Docker containers, and system processes. It can run in terminal mode, launch a local web UI, or export metrics via a REST API.
Installation
# Install glances via pip with full dependency support
pip install glances[all]
# macOS via Homebrew
brew install glances
# Ubuntu/Debian
sudo apt install glances
Running Glances in Various Modes
# Start standard terminal dashboard
glances
# Start web UI server (binds to http://localhost:61208 by default)
glances -w
# Set update interval to 1 second
glances -t 1
# Start metrics server
glances -s
Exporting Metrics to Prometheus
Glances includes a native exporter plugin. To expose metrics to Prometheus, launch Glances with the following flags:
glances --export prometheus --export-prometheus-host 0.0.0.0 --export-prometheus-port 9091
Configure your local Prometheus server to scrape this target:
# prometheus.yml
scrape_configs:
- job_name: "glances-exporter"
static_configs:
- targets: ["localhost:9091"]
scrape_interval: 5s
The exporter publishes metrics such as glances_cpu_total, glances_mem_used, and glances_disk_read_bytes, allowing you to track resource trends in Grafana dashboards.
Monitoring Feature Comparison
| Tool Metric | htop | Glances | default top | btop |
|---|---|---|---|---|
| Refresh Interval | ~0.5s | ~1.5s (Configurable) | ~3.0s | ~1.0s |
| REST API Export | No | Yes (JSON over HTTP) | No | No |
| Docker Container Parsing | No | Yes (Natively displays container names) | No | Yes |
| System Load Overhead | Very Low (<1% CPU) | Low (~2-3% CPU) | Minimal | Low |
| Process Tree Rendering | Yes | No | No | Yes |
What Breaks in Production: Failure Modes and Mitigations
Using terminal monitoring tools can introduce resource overhead or return incomplete data in constrained systems.
1. High CPU Overhead from Rapid Glances Refresh
Glances is written in Python. When configured with high refresh rates (for example, glances -t 0.1 on a multi-core server running hundreds of active processes), the metrics collection engine must perform frequent file queries.
- Failure Mode: The Glances process consumes 10-15% CPU, which can worsen resource constraints on under-provisioned servers.
- Mitigation: Keep the update interval at the default 3 seconds (
-t 3) or higher in production, and run remote diagnostics using server-client mode rather than full UI rendering.
2. Sandbox Permission Denied Errors in Container Runtimes
Container environments (like AWS Fargate, GCP Cloud Run, or secure Docker setups) restrict process access to the host’s /proc virtual file system.
- Failure Mode: Running
htoporglancesinside a secure container throws permission errors or displays empty stats because the tool cannot access core system files. - Mitigation: Run monitoring tools on the host instance rather than inside sandboxed container nodes. If you must inspect container internals, grant standard read permissions to
/procduring debugging sessions:docker run --pid=host -it alpine htop
3. Zombie and Orphan Processes Exhausting PID Space
When parent processes fail to execute the wait() system call on terminated child processes, the children become zombie processes.
- Failure Mode: Zombie processes remain in the system process table, labeled with a
Zstatus inhtop. Over time, they consume PID descriptors, eventually preventing the OS from spawning new processes. - Mitigation: In
htop, sort by state to find the zombie processes, identify their parent process using tree view (F5), and terminate the parent (SIGTERMorSIGKILL) to clean up the orphaned child PIDs.
4. Memory Reclamation Lag in WSL2 Environments
WSL2 runs Linux inside a lightweight utility VM. As build processes create and purge files, the Linux kernel uses free memory for page caching.
- Failure Mode: Windows Task Manager shows high RAM utilization by the WSL2 process (
vmmem), even after compilation completes andhtopshows the memory is free for cache use. The VM does not automatically release this memory back to the Windows host. - Mitigation: Force WSL2 to drop system page caches by running the following command in the WSL console:
echo 3 | sudo tee /proc/sys/vm/drop_caches
Frequently Asked Questions
What is the exact difference between VIRT, RES, and SHR memory in htop?
- VIRT (Virtual Memory): The total memory address space requested by the process, including mapped files, shared libraries, and allocated swap space.
- RES (Resident Set Size): The physical RAM currently allocated to the process. This is the most accurate indicator of a process’s actual memory footprint.
- SHR (Shared Memory): The subset of virtual memory that can be shared with other processes, such as shared library code blocks.
How do I configure Glances to run automatically as a background daemon on boot?
On systemd-managed Linux environments, create a system unit configuration file:
# /etc/systemd/system/glances.service
[Unit]
Description=Glances Monitoring Daemon
After=network.target
[Service]
ExecStart=/usr/local/bin/glances -s -B 0.0.0.0
Restart=on-failure
[Install]
WantedBy=multi-user.target
Enable and start the service using systemctl enable --now glances.
Why does my htop show hundreds of processes when I only started one Node.js server?
By default, htop displays individual hardware threads. If a process spawns multiple worker threads or uses runtime worker pools, htop lists each thread as a separate row. Press H to hide user threads, collapse the list, and display only primary parent processes.
How do I kill a process that refuses to terminate with SIGKILL (signal 9)?
If a process is in state D (uninterruptible sleep, typically waiting for disk or network I/O) or has become a zombie process, the kernel cannot handle the SIGKILL signal. You must resolve the underlying hardware or driver bottleneck, or restart the host system.
Wrapping Up
htop provides interactive process management, making it the tool of choice for diagnosing immediate performance issues. Glances aggregates full-stack metrics and exposes an API, making it suitable for export to external monitoring systems. Using both tools allows you to identify bottlenecks on development and staging servers over SSH without installing complex graphical software.