Master Linux process monitoring using top, htop, and btop to analyze system performance, identify resource bottlenecks, and troubleshoot performance issues in production environments.
Prerequisites
- Root or sudo access to install packages
- Basic understanding of Linux command line
- Terminal access to the system
What this solves
Process monitoring is essential for maintaining healthy Linux systems. When your server is slow, unresponsive, or consuming excessive resources, you need real-time visibility into which processes are using CPU, memory, and I/O. This tutorial covers three essential process monitoring tools: the traditional top command, the interactive htop tool, and the modern btop monitor with advanced visualization.
Understanding Linux process basics
Before diving into monitoring tools, understanding how Linux manages processes helps you interpret the data correctly. Every running program on Linux becomes a process with a unique Process ID (PID). Processes consume system resources like CPU time, memory (RAM), and file descriptors.
Key process states include running (actively using CPU), sleeping (waiting for I/O or events), stopped (paused), and zombie (finished but not cleaned up). Process priority determines CPU scheduling, with lower nice values getting higher priority. Memory usage appears as resident set size (RSS) for physical RAM and virtual memory (VIRT) for total address space.
System load averages show how many processes are actively running or waiting for resources, averaged over 1, 5, and 15 minutes. Load equal to your CPU core count means full utilization, while higher values indicate queuing and potential performance issues.
Step-by-step configuration
Update system packages
Start by updating your package manager to ensure you have access to the latest versions of monitoring tools.
sudo apt update && sudo apt upgrade -y
Install htop for enhanced process monitoring
The top command comes pre-installed on most Linux systems, but htop provides a much more user-friendly interface with color coding and interactive features.
sudo apt install -y htop
Install btop for modern process visualization
btop provides advanced visualizations with graphs, themes, and comprehensive system monitoring in a single interface.
sudo apt install -y btop
Configure top command defaults
You can customize the default top display by creating a personal configuration that persists across sessions.
top
While top is running, press the following keys to customize the display:
1 - Toggle between single CPU and per-core display
f - Select which fields to display
F - Choose sort field
W - Save current configuration to ~/.toprc
q - Quit top
Configure htop preferences
htop stores its configuration in ~/.config/htop/htoprc. You can customize it through the interface or by editing the config file directly.
htop
Use these keys to configure htop while it's running:
F2 - Open setup menu
F3 - Search for processes
F4 - Filter processes
F5 - Tree view toggle
F6 - Sort by different columns
F9 - Kill process
F10 - Quit htop
Create custom htop configuration
Create a custom htop configuration file with optimized settings for system monitoring.
mkdir -p ~/.config/htop
# Htop configuration file
fields=0 48 17 18 38 39 40 2 46 47 49 1
sort_key=46
sort_direction=1
tree_sort_key=0
tree_sort_direction=1
hide_kernel_threads=1
hide_userland_threads=0
shadow_other_users=0
show_thread_names=0
show_program_path=1
highlight_base_name=0
highlight_megabytes=1
highlight_threads=1
highlight_changes=0
highlight_changes_delay_secs=5
find_comm_in_cmdline=1
strip_exe_from_cmdline=1
show_merged_command=0
tree_view=1
tree_view_always_by_pid=0
all_branches_collapsed=0
header_margin=1
detailed_cpu_time=0
cpu_count_from_one=0
show_cpu_usage=1
show_cpu_frequency=0
show_cpu_temperature=0
degree_fahrenheit=0
update_process_names=0
account_guest_in_cpu_meter=0
color_scheme=0
enable_mouse=1
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
Configure btop settings
btop creates its configuration automatically on first run. You can customize themes, update intervals, and display options.
btop
btop configuration options (press ESC to access menu):
ESC - Open main menu
q - Quit btop
m - Show menu
o - Options menu
h - Help menu
+ - Increase update speed
- - Decrease update speed
Set up process monitoring aliases
Create convenient shell aliases for different monitoring scenarios.
# Process monitoring aliases
alias topcpu='top -o %CPU'
alias topmem='top -o %MEM'
alias htree='htop -t'
alias btopmin='btop --update 1000'
Resource monitoring shortcuts
alias procwatch='watch -n 1 "ps aux --sort=-%cpu | head -20"'
alias memwatch='watch -n 1 "free -h && echo && ps aux --sort=-%mem | head -10"'
System load monitoring
alias loadavg='uptime && cat /proc/loadavg'
Reload your bash configuration to activate the aliases:
source ~/.bashrc
Using top for basic process monitoring
The traditional top command provides real-time process and system information. The header shows system uptime, user sessions, load averages, CPU usage breakdown, and memory statistics.
top
Key top command options for different monitoring scenarios:
# Show processes for specific user
top -u www-data
Sort by memory usage instead of CPU
top -o %MEM
Show process tree relationships
top -c
Limit display to top 10 processes
top -n 1 | head -20
Batch mode for logging (no interaction)
top -b -n 1 > top_snapshot.txt
Understanding top output fields helps you identify performance issues quickly. PID shows the process ID, USER indicates process owner, PR displays priority, NI shows nice value, VIRT shows virtual memory, RES displays resident memory, SHR shows shared memory, S indicates process state, %CPU shows CPU percentage, %MEM displays memory percentage, and COMMAND shows the process name.
Advanced htop features
htop provides enhanced visualization and interactive features that make process management more efficient. The color-coded interface shows CPU and memory usage with visual bars, making it easier to spot resource-intensive processes.
htop
Essential htop interactive features include process filtering, sorting by different columns, tree view for parent-child relationships, and direct process management. You can search for specific processes using F3, filter the display with F4, and toggle tree view with F5.
htop allows you to perform process management tasks directly from the interface. Select a process with arrow keys and use F9 to send signals like TERM or KILL. You can change process priorities with F7 (decrease) and F8 (increase), which adjusts the nice value.
# Start htop with specific options
htop -d 10 # Update every 10 seconds
htop -u apache # Show only apache user processes
htop -p 1234,5678 # Monitor specific PIDs
htop -t # Start in tree mode
Modern monitoring with btop
btop offers the most comprehensive system monitoring with graphs, advanced themes, and network monitoring. The interface displays CPU usage graphs, memory utilization charts, disk I/O statistics, and network activity in a unified dashboard.
btop
btop provides detailed system metrics including per-core CPU usage graphs, memory breakdown between used, cached, and available, disk usage for all mounted filesystems, and network traffic statistics. The process list shows CPU and memory usage with sorting options and process management capabilities.
Key btop navigation commands help you customize the monitoring experience. Use the arrow keys to navigate between sections, Tab to cycle through process sort options, and + or - to adjust update frequency. The ESC key opens the configuration menu where you can change themes, adjust display options, and modify update intervals.
# Run btop with specific settings
btop --update 500 # Update every 500ms
btop --preset 1 # Use preset configuration 1
Interpreting system metrics
Understanding the metrics displayed by these tools helps you identify and resolve performance issues. CPU usage shows how much processing power each process consumes, with high values indicating CPU-intensive tasks. Load average represents the number of processes waiting for CPU time, with values above your CPU core count suggesting system overload.
Memory metrics require careful interpretation to avoid false alarms. Linux uses available memory for disk caching, so high memory usage doesn't necessarily indicate problems. Focus on the "available" memory figure rather than "free" memory. Swap usage should remain low during normal operation, as heavy swapping indicates insufficient RAM.
Process states provide insight into system behavior. Running processes actively use CPU, while sleeping processes wait for I/O operations or user input. A large number of processes in uninterruptible sleep (D state) might indicate I/O bottlenecks or storage issues.
| Metric | Normal Range | Warning Signs |
|---|---|---|
| Load Average | Below CPU core count | Consistently above core count |
| Memory Usage | 70-80% with low swap | 90%+ memory with active swap |
| CPU Usage | Varies by workload | Single process at 100% for extended periods |
| Process Count | Varies by system role | Rapidly increasing process count |
Troubleshooting performance issues
When investigating performance problems, start by identifying the resource bottleneck. High CPU usage with low load averages suggests CPU-intensive tasks, while high load averages with moderate CPU usage indicate I/O bottlenecks. Memory pressure appears as high swap usage or frequent page faults.
Common performance investigation workflows begin with checking system load and identifying top resource consumers. Use top -o %CPU to find CPU-intensive processes, top -o %MEM for memory hogs, and iotop for disk I/O analysis (if available). Process trees in htop help identify parent processes spawning excessive children.
For investigating specific processes, note the PID and use additional tools for detailed analysis. The ps command shows process relationships, while lsof displays open files and network connections. System logs in /var/log/ often contain error messages related to problematic processes.
# Investigate high-CPU process with PID 1234
ps -p 1234 -o pid,ppid,cmd,etime
lsof -p 1234
strace -p 1234 -c
Check system resources
free -h
df -h
uptime
cat /proc/loadavg
Performance monitoring integrates well with other system administration tasks. For comprehensive system monitoring, consider combining process monitoring with sar and sysstat for detailed performance metrics or implementing Netdata for real-time performance dashboards.
Automation and alerting
Process monitoring becomes more powerful when automated for proactive system management. Create scripts that check for specific conditions and alert administrators before problems impact users.
Create process monitoring script
Build a script that monitors system resources and sends alerts when thresholds are exceeded.
#!/bin/bash
Configuration
CPU_THRESHOLD=80
MEM_THRESHOLD=90
LOAD_THRESHOLD=4
ALERT_EMAIL="admin@example.com"
Get current metrics
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
MEM_USAGE=$(free | grep Mem | awk '{printf "%.0f", $3/$2 * 100.0}')
LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | sed 's/^ *//')
Check CPU usage
if (( $(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc -l) )); then
echo "High CPU usage: $CPU_USAGE%" | mail -s "CPU Alert" $ALERT_EMAIL
logger "High CPU usage detected: $CPU_USAGE%"
fi
Check memory usage
if [ "$MEM_USAGE" -gt "$MEM_THRESHOLD" ]; then
echo "High memory usage: $MEM_USAGE%" | mail -s "Memory Alert" $ALERT_EMAIL
logger "High memory usage detected: $MEM_USAGE%"
fi
Check load average
if (( $(echo "$LOAD_AVG > $LOAD_THRESHOLD" | bc -l) )); then
echo "High load average: $LOAD_AVG" | mail -s "Load Alert" $ALERT_EMAIL
logger "High load average detected: $LOAD_AVG"
fi
Log current status
echo "$(date): CPU=$CPU_USAGE% MEM=$MEM_USAGE% LOAD=$LOAD_AVG" >> /var/log/process_monitor.log
Make the script executable:
sudo chmod +x /usr/local/bin/process_monitor.sh
Set up automated monitoring
Add the monitoring script to cron for regular execution.
sudo crontab -e
Add this line to run the monitor every 5 minutes:
/5 * /usr/local/bin/process_monitor.sh
Verify your setup
Test all three monitoring tools to ensure they're working correctly and providing accurate system information.
# Test basic top functionality
top -n 1
Verify htop installation and config
htop --version
ls -la ~/.config/htop/htoprc
Test btop functionality
btop --help
Check monitoring script
sudo /usr/local/bin/process_monitor.sh
tail -n 5 /var/log/process_monitor.log
Verify cron job
sudo crontab -l | grep process_monitor
Launch each tool and verify the display shows current system information. htop should display colored bars and respond to function keys, while btop should show graphs and detailed system metrics. The monitoring script should execute without errors and log current system status.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| btop not available in package manager | Outdated distribution repositories | Install from GitHub releases or enable additional repositories |
| htop shows incorrect CPU count | Virtualization or container limits | Check /proc/cpuinfo and container resource limits |
| Process monitoring script fails | Missing mail command or bc calculator | sudo apt install mailutils bc or sudo dnf install mailx bc |
| top shows high load but low CPU | I/O wait or uninterruptible sleep processes | Check disk I/O with iostat and investigate D-state processes |
| Memory usage appears too high | Normal Linux caching behavior | Focus on "available" memory, not "free" memory in output |
| Configuration changes don't persist | Incorrect file permissions or paths | Ensure config directories exist and are writable by user |
Next steps
- Set up comprehensive performance monitoring with sar and sysstat
- Deploy Netdata for real-time system monitoring dashboards
- Configure resource limits and quotas with systemd
- Set up advanced system alerting with Prometheus and Grafana
- Optimize system performance with kernel parameter tuning
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly NC='\033[0m'
# Global variables
PKG_MGR=""
PKG_INSTALL=""
UPDATE_CMD=""
# Logging functions
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Usage information
usage() {
cat << EOF
Usage: $0 [OPTIONS]
Install and configure Linux process monitoring tools (top, htop, btop)
OPTIONS:
-h, --help Show this help message
--minimal Install only htop (skip btop)
--user-only Configure only for current user (no system updates)
Examples:
$0 # Full installation
$0 --minimal # Install htop only
$0 --user-only # User configuration only
EOF
}
# Cleanup on error
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
log_error "Installation failed. Rolling back changes..."
# Remove any partially created config files
[ -f ~/.config/htop/htoprc.backup ] && mv ~/.config/htop/htoprc.backup ~/.config/htop/htoprc 2>/dev/null || true
[ -f ~/.toprc.backup ] && mv ~/.toprc.backup ~/.toprc 2>/dev/null || true
fi
exit $exit_code
}
trap cleanup ERR
# Detect distribution and package manager
detect_distro() {
log_info "Detecting Linux distribution..."
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
UPDATE_CMD="apt update && apt upgrade -y"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
UPDATE_CMD="dnf update -y"
;;
fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
UPDATE_CMD="dnf update -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
UPDATE_CMD="yum update -y"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
log_success "Detected $PRETTY_NAME using $PKG_MGR"
else
log_error "Cannot detect Linux distribution (/etc/os-release not found)"
exit 1
fi
}
# Check prerequisites
check_prerequisites() {
log_info "Checking prerequisites..."
# Check if user has sudo privileges (if not running user-only mode)
if [ "${USER_ONLY:-false}" != "true" ]; then
if ! sudo -n true 2>/dev/null; then
log_error "This script requires sudo privileges"
exit 1
fi
fi
# Check if package manager is available
if ! command -v "$PKG_MGR" >/dev/null 2>&1; then
log_error "Package manager $PKG_MGR not found"
exit 1
fi
log_success "Prerequisites check passed"
}
# Update system packages
update_system() {
if [ "${USER_ONLY:-false}" = "true" ]; then
log_info "Skipping system update (user-only mode)"
return
fi
echo "[1/6] Updating system packages..."
log_info "Running system update..."
if sudo bash -c "$UPDATE_CMD"; then
log_success "System packages updated successfully"
else
log_warning "System update encountered issues, continuing..."
fi
}
# Install htop
install_htop() {
if [ "${USER_ONLY:-false}" = "true" ]; then
log_info "Skipping htop installation (user-only mode)"
return
fi
echo "[2/6] Installing htop..."
if command -v htop >/dev/null 2>&1; then
log_info "htop is already installed"
return
fi
log_info "Installing htop..."
sudo bash -c "$PKG_INSTALL htop"
log_success "htop installed successfully"
}
# Install btop
install_btop() {
if [ "${USER_ONLY:-false}" = "true" ]; then
log_info "Skipping btop installation (user-only mode)"
return
fi
if [ "${MINIMAL:-false}" = "true" ]; then
log_info "Skipping btop installation (minimal mode)"
return
fi
echo "[3/6] Installing btop..."
if command -v btop >/dev/null 2>&1; then
log_info "btop is already installed"
return
fi
log_info "Installing btop..."
# Enable EPEL for RHEL-based systems if needed
if [ "$PKG_MGR" = "dnf" ] && [ "$ID" != "fedora" ]; then
if ! dnf repolist | grep -q epel; then
log_info "Enabling EPEL repository for btop..."
sudo dnf install -y epel-release || log_warning "Could not enable EPEL, btop may not be available"
fi
fi
if sudo bash -c "$PKG_INSTALL btop"; then
log_success "btop installed successfully"
else
log_warning "btop installation failed, continuing without btop"
fi
}
# Configure htop
configure_htop() {
echo "[4/6] Configuring htop..."
local htop_dir="$HOME/.config/htop"
local htop_config="$htop_dir/htoprc"
# Create htop config directory
mkdir -p "$htop_dir"
# Backup existing config
if [ -f "$htop_config" ]; then
cp "$htop_config" "$htop_config.backup"
log_info "Backed up existing htop configuration"
fi
# Create optimized htop configuration
cat > "$htop_config" << 'EOF'
fields=0 48 17 18 38 39 40 2 46 47 49 1
sort_key=46
sort_direction=1
tree_sort_key=0
tree_sort_direction=1
hide_kernel_threads=1
hide_userland_threads=0
shadow_other_users=0
show_thread_names=0
show_program_path=1
highlight_base_name=0
highlight_megabytes=1
highlight_threads=1
highlight_changes=0
highlight_changes_delay_secs=5
find_comm_in_cmdline=1
strip_exe_from_cmdline=1
show_merged_command=0
tree_view=1
tree_view_always_by_pid=0
all_branches_collapsed=0
header_margin=1
detailed_cpu_time=0
cpu_count_from_one=0
show_cpu_usage=1
show_cpu_frequency=0
show_cpu_temperature=0
degree_fahrenheit=0
update_process_names=0
account_guest_in_cpu_meter=0
color_scheme=0
enable_mouse=1
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
chmod 644 "$htop_config"
log_success "htop configuration created"
}
# Configure top
configure_top() {
echo "[5/6] Creating top configuration guide..."
# Create a simple script to help users configure top
cat > "$HOME/.toprc_setup.sh" << 'EOF'
#!/bin/bash
echo "To configure top with recommended settings:"
echo "1. Run 'top'"
echo "2. Press '1' to show individual CPU cores"
echo "3. Press 'f' to select fields, then 'q' to return"
echo "4. Press 'W' to save configuration"
echo "5. Press 'q' to quit"
echo ""
echo "Useful top commands:"
echo "- Press 'M' to sort by memory usage"
echo "- Press 'P' to sort by CPU usage"
echo "- Press 'k' to kill a process"
echo "- Press 'r' to renice a process"
EOF
chmod 755 "$HOME/.toprc_setup.sh"
log_success "Top configuration guide created at ~/.toprc_setup.sh"
}
# Verify installation
verify_installation() {
echo "[6/6] Verifying installation..."
local tools_installed=0
local tools_total=1 # top is always available
# Check top (always available)
if command -v top >/dev/null 2>&1; then
log_success "top is available"
tools_installed=$((tools_installed + 1))
fi
# Check htop if not in user-only mode
if [ "${USER_ONLY:-false}" != "true" ]; then
tools_total=$((tools_total + 1))
if command -v htop >/dev/null 2>&1; then
log_success "htop is available"
tools_installed=$((tools_installed + 1))
else
log_warning "htop is not available"
fi
fi
# Check btop if not in minimal or user-only mode
if [ "${MINIMAL:-false}" != "true" ] && [ "${USER_ONLY:-false}" != "true" ]; then
tools_total=$((tools_total + 1))
if command -v btop >/dev/null 2>&1; then
log_success "btop is available"
tools_installed=$((tools_installed + 1))
else
log_warning "btop is not available"
fi
fi
# Check htop configuration
if [ -f "$HOME/.config/htop/htoprc" ]; then
log_success "htop configuration is in place"
else
log_warning "htop configuration not found"
fi
log_success "Installation complete! ($tools_installed/$tools_total tools available)"
echo ""
echo "Quick start:"
echo "- Run 'top' for basic process monitoring"
[ "${USER_ONLY:-false}" != "true" ] && echo "- Run 'htop' for enhanced interactive monitoring"
[ "${MINIMAL:-false}" != "true" ] && [ "${USER_ONLY:-false}" != "true" ] && echo "- Run 'btop' for modern visualization"
echo "- Run '~/.toprc_setup.sh' for top configuration help"
}
# Main function
main() {
local MINIMAL=false
local USER_ONLY=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
usage
exit 0
;;
--minimal)
MINIMAL=true
shift
;;
--user-only)
USER_ONLY=true
shift
;;
*)
log_error "Unknown option: $1"
usage
exit 1
;;
esac
done
log_info "Starting Linux process monitoring tools installation..."
detect_distro
check_prerequisites
update_system
install_htop
install_btop
configure_htop
configure_top
verify_installation
log_success "Process monitoring tools setup completed successfully!"
}
# Only run main if script is executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
Review the script before running. Execute with: bash install.sh