Learn to use htop for advanced Linux system monitoring, process management, and performance optimization. Master resource analysis, identify bottlenecks, and automate monitoring tasks for production environments.
Prerequisites
- Root or sudo access
- Basic command line knowledge
- Understanding of Linux processes
What this solves
htop provides real-time system monitoring with color-coded process visualization, resource usage tracking, and interactive process management. This tutorial teaches you to identify CPU bottlenecks, memory leaks, high I/O processes, and system resource contention using htop's advanced features. You'll learn to optimize system performance based on htop analysis and automate monitoring tasks for production environments.
Step-by-step installation
Update system packages
Update your package manager to ensure you get the latest htop version with all features.
sudo apt update && sudo apt upgrade -y
Install htop and monitoring tools
Install htop along with additional system monitoring utilities for comprehensive performance analysis.
sudo apt install -y htop iotop atop nethogs sysstat procps
Launch htop and explore interface
Start htop to familiarize yourself with the color-coded interface and navigation controls.
htop
Configure htop display preferences
Customize htop's display to show additional metrics and optimize the layout for your monitoring needs.
htop
In htop interface, press F2 for Setup menu and configure:
- Colors: Enable color coding for better process identification
- Columns: Add PPID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT
- Display options: Show full command paths, highlight program names
- Meters: Add CPU average, I/O rate, network I/O if available
Understanding htop interface and metrics
Interpret CPU and memory indicators
Learn to read htop's color-coded bars and understand what each metric represents for system performance.
| Color | CPU Usage Type | Memory Type |
|---|---|---|
| Green | User processes | Used memory |
| Red | System/kernel processes | Buffers |
| Yellow | I/O wait time | Cache |
| Blue | Low priority processes | Available memory |
| Magenta | Soft IRQ | Shared memory |
Analyze process information columns
Understand the key metrics displayed for each process to identify performance bottlenecks.
| Column | Description | Performance Impact |
|---|---|---|
| PID | Process ID | Unique identifier for process management |
| USER | Process owner | Security context and resource limits |
| CPU% | CPU usage percentage | High values indicate CPU-bound processes |
| MEM% | Memory usage percentage | High values may indicate memory leaks |
| RES | Resident memory (RAM) | Actual physical memory usage |
| SHR | Shared memory | Memory shared with other processes |
| S | Process state | R=Running, S=Sleeping, D=Disk sleep |
Identify performance bottlenecks with htop
Monitor CPU-intensive processes
Use htop to identify processes consuming excessive CPU resources and understand their impact on system performance.
# Launch htop and sort by CPU usage
htop
Press F6 for sort menu, select CPU%
Press 'c' to show full command lines
Press 'H' to show/hide threads
Look for processes with consistently high CPU% values above 80-90% or multiple processes competing for CPU time.
Identify memory bottlenecks and leaks
Monitor memory usage patterns to detect memory leaks, swap usage, and insufficient RAM allocation.
# Sort by memory usage in htop
Press F6, select MEM%
Monitor these indicators:
- High swap usage (yellow/red swap bar)
- Processes with growing RES values
- Low available memory (check memory bar)
Monitor I/O bottlenecks
Use htop alongside iotop to identify processes causing high disk I/O that may slow down system performance.
# Check for I/O wait in htop (yellow sections in CPU bars)
htop
Run iotop in another terminal to see disk I/O per process
sudo iotop -o -d 1
Monitor network I/O with nethogs
sudo nethogs
High I/O wait times (yellow in CPU bars) combined with specific processes showing high disk usage indicates I/O bottlenecks.
Analyze system load and process states
Monitor load averages and process states to understand overall system health and resource contention.
# Check load averages (top-left in htop)
Load average meanings:
- Below CPU count: System has spare capacity
- Equal to CPU count: System fully utilized
- Above CPU count: System overloaded
Monitor process states:
- Too many 'R' (running): CPU overload
- Many 'D' (disk sleep): I/O bottleneck
- High 'Z' (zombie): Process cleanup issues
Optimize system performance based on htop analysis
Manage resource-intensive processes
Use htop's interactive features to control processes that are consuming excessive system resources.
# In htop interface:
Navigate to problematic process with arrow keys
Press 'r' to renice (change priority)
Enter new nice value: -20 (highest) to 19 (lowest)
Press 'k' to kill process (sends SIGTERM)
Press 'F9' for kill menu with different signals
Configure process priorities and limits
Set permanent process priorities and resource limits to prevent future performance issues.
# Add resource limits for specific users or groups
@developers soft nproc 1024
@developers hard nproc 2048
@developers soft memlock 102400
@developers hard memlock 204800
Limit CPU time for background processes
@background soft cpu 3600
@background hard cpu 7200
Optimize memory usage
Configure system memory settings based on htop analysis to improve overall performance.
# Reduce swap usage priority (0-100, lower = less swap)
vm.swappiness = 10
Increase dirty page cache for better I/O performance
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
Optimize cache pressure (0-200, lower = keep cache longer)
vm.vfs_cache_pressure = 50
sudo sysctl -p /etc/sysctl.d/99-memory-optimization.conf
Configure CPU scheduling optimization
Optimize CPU scheduling based on your workload characteristics identified through htop monitoring.
# Optimize for desktop/interactive workloads
kernel.sched_autogroup_enabled = 1
kernel.sched_tunable_scaling = 0
Reduce context switching overhead
kernel.sched_migration_cost_ns = 5000000
kernel.sched_nr_migrate = 32
sudo sysctl -p /etc/sysctl.d/99-cpu-optimization.conf
Set up htop monitoring scripts and automation
Create htop monitoring script
Develop a script to capture htop data for automated analysis and alerting based on performance thresholds.
#!/bin/bash
htop-based system monitoring script
LOG_FILE="/var/log/htop-monitor.log"
ALERT_EMAIL="admin@example.com"
CPU_THRESHOLD=80
MEM_THRESHOLD=85
Get current system metrics
LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ',')
CPU_COUNT=$(nproc)
MEM_USAGE=$(free | awk 'NR==2{printf "%.1f", $3*100/$2}')
Check CPU load
if (( $(echo "$LOAD_AVG > $CPU_COUNT * 0.8" | bc -l) )); then
echo "$(date): High CPU load detected: $LOAD_AVG" >> "$LOG_FILE"
# Get top CPU processes
ps aux --sort=-%cpu | head -n 6 >> "$LOG_FILE"
fi
Check memory usage
if (( $(echo "$MEM_USAGE > $MEM_THRESHOLD" | bc -l) )); then
echo "$(date): High memory usage detected: ${MEM_USAGE}%" >> "$LOG_FILE"
# Get top memory processes
ps aux --sort=-%mem | head -n 6 >> "$LOG_FILE"
fi
Log current top processes
echo "$(date): System snapshot" >> "$LOG_FILE"
echo "Load: $LOAD_AVG, Memory: ${MEM_USAGE}%" >> "$LOG_FILE"
ps aux --sort=-%cpu | head -n 4 >> "$LOG_FILE"
echo "---" >> "$LOG_FILE"
sudo chmod +x /usr/local/bin/htop-monitor.sh
Set up automated monitoring with systemd timer
Create a systemd service and timer to run htop monitoring automatically at regular intervals.
[Unit]
Description=htop System Monitoring
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/htop-monitor.sh
User=root
StandardOutput=journal
StandardError=journal
[Unit]
Description=Run htop monitoring every 5 minutes
Requires=htop-monitor.service
[Timer]
OnCalendar=*:0/5
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now htop-monitor.timer
sudo systemctl status htop-monitor.timer
Create htop configuration backup
Save your htop configuration for consistent monitoring across systems and team members.
# Export current htop configuration
cp ~/.config/htop/htoprc /tmp/htop-config-backup
Create system-wide htop configuration
sudo mkdir -p /etc/htop
sudo cp ~/.config/htop/htoprc /etc/htop/htoprc
Make it readable by all users
sudo chmod 644 /etc/htop/htoprc
Set up performance alerting script
Create an alert script that triggers when htop metrics exceed defined thresholds for proactive performance management.
#!/bin/bash
Performance alerting based on htop metrics
SMTP_SERVER="smtp.example.com"
ALERT_EMAIL="sysadmin@example.com"
HOSTNAME=$(hostname)
Function to send alert email
send_alert() {
local subject="$1"
local message="$2"
echo "Subject: $subject" > /tmp/alert.txt
echo "From: monitor@$HOSTNAME" >> /tmp/alert.txt
echo "" >> /tmp/alert.txt
echo "$message" >> /tmp/alert.txt
echo "" >> /tmp/alert.txt
echo "Current top processes:" >> /tmp/alert.txt
ps aux --sort=-%cpu | head -n 10 >> /tmp/alert.txt
# Use mail command or configure with your SMTP setup
mail -s "$subject" "$ALERT_EMAIL" < /tmp/alert.txt
rm /tmp/alert.txt
}
Check for critical processes
CRIT_CPU=$(ps aux --sort=-%cpu | awk 'NR==2{print $3}' | cut -d. -f1)
if [ "$CRIT_CPU" -gt 90 ]; then
PROC_NAME=$(ps aux --sort=-%cpu | awk 'NR==2{print $11}')
send_alert "Critical CPU Usage on $HOSTNAME" "Process $PROC_NAME is using ${CRIT_CPU}% CPU"
fi
sudo chmod +x /usr/local/bin/performance-alert.sh
Verify your setup
Test htop functionality and configuration
Verify that htop is properly installed and configured with all monitoring features working correctly.
# Check htop installation and version
htop --version
Verify monitoring tools are available
which iotop nethogs atop
Test monitoring script
sudo /usr/local/bin/htop-monitor.sh
cat /var/log/htop-monitor.log
Check systemd timer status
sudo systemctl status htop-monitor.timer
sudo systemctl list-timers htop-monitor.timer
Validate performance optimizations
Confirm that system optimizations are applied and monitor their impact on performance metrics.
# Check applied sysctl settings
sudo sysctl vm.swappiness vm.dirty_ratio vm.vfs_cache_pressure
sudo sysctl kernel.sched_autogroup_enabled
Monitor system performance
htop &
iotop -o -d 2 &
Generate some load and observe
stress-ng --cpu 2 --timeout 30s
Kill background monitoring
killall htop iotop
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| htop shows incorrect CPU count | Old htop version or virtualization | Update htop: sudo apt update && sudo apt install htop |
| Cannot see other users' processes | Running htop as non-root user | Run sudo htop or add user to appropriate groups |
| htop configuration not saved | Missing .config/htop directory | Create directory: mkdir -p ~/.config/htop |
| Monitoring script permission denied | Script not executable or wrong ownership | Fix permissions: sudo chown root:root script && sudo chmod 755 script |
| High memory usage but low RES values | Memory used for buffers/cache | Check available memory, not used memory in htop header |
| Load average higher than CPU usage | Processes waiting for I/O or other resources | Check iotop for disk I/O bottlenecks and system logs |
Next steps
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Global variables
PKG_MGR=""
PKG_INSTALL=""
PKG_UPDATE=""
HTOP_CONFIG_DIR=""
USER_HOME=""
# Cleanup function for rollback
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
echo -e "${RED}[ERROR] Installation failed. Check the output above for details.${NC}"
fi
exit $exit_code
}
# Set trap for cleanup
trap cleanup ERR
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to detect distribution
detect_distro() {
if [ ! -f /etc/os-release ]; then
print_error "Cannot detect Linux distribution. /etc/os-release not found."
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
;;
*)
print_error "Unsupported distribution: $ID"
exit 1
;;
esac
print_status "Detected distribution: $PRETTY_NAME"
print_status "Using package manager: $PKG_MGR"
}
# Function to check prerequisites
check_prerequisites() {
# Check if running as root or with sudo
if [[ $EUID -eq 0 ]]; then
print_warning "Running as root user"
USER_HOME="/root"
else
if ! command -v sudo &> /dev/null; then
print_error "This script requires sudo privileges. Please install sudo or run as root."
exit 1
fi
USER_HOME="$HOME"
fi
# Set htop config directory based on user
if [[ $EUID -eq 0 ]]; then
HTOP_CONFIG_DIR="/root/.config/htop"
else
HTOP_CONFIG_DIR="$HOME/.config/htop"
fi
# Check internet connectivity
if ! ping -c 1 8.8.8.8 &> /dev/null; then
print_warning "No internet connectivity detected. Package installation may fail."
fi
}
# Function to update system packages
update_system() {
print_status "Updating system packages..."
if [[ $EUID -eq 0 ]]; then
eval "$PKG_UPDATE"
else
sudo bash -c "$PKG_UPDATE"
fi
print_status "System packages updated successfully"
}
# Function to install monitoring tools
install_monitoring_tools() {
print_status "Installing htop and additional monitoring tools..."
# Define packages based on distribution
local packages="htop sysstat procps"
case "$PKG_MGR" in
apt)
packages="$packages iotop atop nethogs"
;;
dnf|yum)
packages="$packages iotop atop nethogs procps-ng"
;;
esac
if [[ $EUID -eq 0 ]]; then
eval "$PKG_INSTALL $packages"
else
sudo bash -c "$PKG_INSTALL $packages"
fi
print_status "Monitoring tools installed successfully"
}
# Function to create htop configuration
create_htop_config() {
print_status "Creating optimized htop configuration..."
# Create config directory if it doesn't exist
mkdir -p "$HTOP_CONFIG_DIR"
# Create optimized htop configuration file
cat > "$HTOP_CONFIG_DIR/htoprc" << 'EOF'
# Beware! This file is rewritten by htop when settings are changed in the interface.
# The parser is also very primitive, and not human-friendly.
fields=0 48 17 18 38 39 40 2 46 47 49 1
sort_key=46
sort_direction=1
hide_threads=0
hide_kernel_threads=1
hide_userland_threads=0
shadow_other_users=0
show_thread_names=0
show_program_path=1
highlight_base_name=1
highlight_megabytes=1
highlight_threads=1
tree_view=0
header_margin=1
detailed_cpu_time=0
cpu_count_from_zero=0
update_process_names=0
account_guest_in_cpu_meter=0
color_scheme=0
delay=15
left_meters=LeftCPUs Memory Swap
left_meter_modes=1 1 1
right_meters=RightCPUs Tasks LoadAverage Uptime
right_meter_modes=1 2 2 2
EOF
# Set proper ownership and permissions
if [[ $EUID -eq 0 ]]; then
chown root:root "$HTOP_CONFIG_DIR/htoprc"
else
chown "$USER:$USER" "$HTOP_CONFIG_DIR/htoprc"
fi
chmod 644 "$HTOP_CONFIG_DIR/htoprc"
print_status "htop configuration created at $HTOP_CONFIG_DIR/htoprc"
}
# Function to create monitoring scripts
create_monitoring_scripts() {
print_status "Creating system monitoring helper scripts..."
local script_dir="/usr/local/bin"
# Create system performance overview script
cat > "$script_dir/sysperf" << 'EOF'
#!/bin/bash
echo "=== System Performance Overview ==="
echo "Date: $(date)"
echo
echo "=== CPU Information ==="
grep 'model name' /proc/cpuinfo | head -1
echo "CPU Cores: $(nproc)"
echo
echo "=== Memory Usage ==="
free -h
echo
echo "=== Disk Usage ==="
df -h / | tail -1
echo
echo "=== Load Average ==="
uptime
echo
echo "=== Top 5 CPU Processes ==="
ps aux --sort=-%cpu | head -6
echo
echo "=== Top 5 Memory Processes ==="
ps aux --sort=-%mem | head -6
EOF
chmod 755 "$script_dir/sysperf"
# Create I/O monitoring script
cat > "$script_dir/iocheck" << 'EOF'
#!/bin/bash
echo "=== I/O Performance Check ==="
echo "Note: Run with sudo for detailed per-process I/O statistics"
echo
if command -v iostat &> /dev/null; then
echo "=== Disk I/O Statistics (5 second average) ==="
iostat -x 1 5 | tail -20
else
echo "iostat not available. Install sysstat package."
fi
echo
if [ "$EUID" -eq 0 ] && command -v iotop &> /dev/null; then
echo "=== Top I/O Processes ==="
timeout 10 iotop -b -n 5 -o | head -20
fi
EOF
chmod 755 "$script_dir/iocheck"
print_status "Helper scripts created: sysperf, iocheck"
}
# Function to enable and configure sysstat
configure_sysstat() {
print_status "Configuring system statistics collection..."
case "$PKG_MGR" in
apt)
# Enable sysstat data collection on Debian-based systems
if [ -f /etc/default/sysstat ]; then
if [[ $EUID -eq 0 ]]; then
sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
else
sudo sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
fi
fi
;;
esac
# Start and enable sysstat service
if command -v systemctl &> /dev/null; then
if [[ $EUID -eq 0 ]]; then
systemctl enable sysstat || true
systemctl start sysstat || true
else
sudo systemctl enable sysstat || true
sudo systemctl start sysstat || true
fi
fi
print_status "System statistics collection configured"
}
# Function to verify installation
verify_installation() {
print_status "Verifying installation..."
local failed=0
# Check if htop is installed and working
if ! command -v htop &> /dev/null; then
print_error "htop installation failed"
failed=1
else
print_status "✓ htop installed successfully"
fi
# Check htop configuration
if [ ! -f "$HTOP_CONFIG_DIR/htoprc" ]; then
print_error "htop configuration not found"
failed=1
else
print_status "✓ htop configuration created"
fi
# Check additional tools
for tool in iotop sysstat; do
if command -v $tool &> /dev/null || dpkg -l | grep -q $tool || rpm -q $tool &> /dev/null; then
print_status "✓ $tool installed"
else
print_warning "$tool installation may have failed"
fi
done
# Check helper scripts
for script in sysperf iocheck; do
if [ -x "/usr/local/bin/$script" ]; then
print_status "✓ $script helper script created"
else
print_error "$script helper script creation failed"
failed=1
fi
done
if [ $failed -eq 1 ]; then
print_error "Some components failed to install properly"
exit 1
fi
}
# Function to display usage information
show_usage() {
print_status "=== System Performance Monitoring Setup Complete ==="
echo
echo "Installed tools:"
echo " • htop - Interactive process viewer with optimized configuration"
echo " • iotop - I/O usage monitor (requires sudo)"
echo " • atop - Advanced system monitor"
echo " • nethogs - Network usage monitor (requires sudo)"
echo " • sysstat - System performance statistics"
echo
echo "Helper scripts created:"
echo " • sysperf - Quick system performance overview"
echo " • iocheck - I/O performance analysis"
echo
echo "Usage examples:"
echo " htop # Launch interactive process monitor"
echo " sysperf # System performance overview"
echo " sudo iocheck # I/O performance check"
echo " sudo iotop -o # Show only processes with I/O activity"
echo " sudo nethogs # Monitor network usage by process"
echo " iostat -x 1 # Continuous I/O statistics"
echo
echo "htop configuration:"
echo " Config file: $HTOP_CONFIG_DIR/htoprc"
echo " • Optimized layout with additional columns (PPID, USER, etc.)"
echo " • Color-coded process visualization enabled"
echo " • Full command paths displayed"
echo
print_status "Installation completed successfully!"
}
# Main execution
main() {
echo -e "${BLUE}=== Linux System Performance Monitoring Setup ===${NC}"
echo "[1/7] Checking prerequisites..."
check_prerequisites
echo "[2/7] Detecting distribution..."
detect_distro
echo "[3/7] Updating system packages..."
update_system
echo "[4/7] Installing monitoring tools..."
install_monitoring_tools
echo "[5/7] Creating htop configuration..."
create_htop_config
echo "[6/7] Creating helper scripts..."
create_monitoring_scripts
configure_sysstat
echo "[7/7] Verifying installation..."
verify_installation
show_usage
}
# Run main function
main "$@"
Review the script before running. Execute with: bash install.sh