Skip to content

Performance Troubleshooting Guide

When your Raspberry Pi feels slow, freezes, or crashes, this guide will help you systematically diagnose the root cause and fix it. Follow the diagnostic flowcharts to quickly identify whether the problem is CPU, memory, storage, network, or thermal.

Quick Diagnostic Overview

Start here to identify the type of performance issue:

graph TD A[Pi is slow or unresponsive] --> B{Check temperature via vcgencmd} B -->|Over 80C| C[Thermal throttling - Go to Thermal section] B -->|Under 80C| D{Check CPU usage via top or htop} D -->|Over 90 percent| E[CPU bottleneck - Go to CPU section] D -->|Under 90 percent| F{Check memory via free -h} F -->|Low free memory and Swap in use| G[Memory pressure - Go to Memory section] F -->|Memory OK| H{Check disk IO via iostat or iotop} H -->|High IO wait| I[Storage bottleneck - Go to Storage section] H -->|IO OK| J[Network or app issue - Go to Network section] style C fill:#ff6b6b,stroke:#333,color:#fff style E fill:#ffa94d,stroke:#333,color:#fff style G fill:#ffd43b,stroke:#333,color:#000 style I fill:#69db7c,stroke:#333,color:#000 style J fill:#4dabf7,stroke:#333,color:#fff

Essential Monitoring Commands

Before diving into specific issues, familiarize yourself with these diagnostic tools:

# Install monitoring tools (if not already present)
sudo apt install htop iotop sysstat net-tools

# All-in-one system overview
htop

# Quick status check
echo "=== Temperature ===" && vcgencmd measure_temp
echo "=== CPU ===" && cat /proc/loadavg
echo "=== Memory ===" && free -h
echo "=== Disk ===" && df -h /
echo "=== Throttling ===" && vcgencmd get_throttled

CPU Troubleshooting

Symptoms

  • Commands take a long time to execute
  • Desktop UI is laggy
  • Programs respond slowly
  • Fan runs constantly (on cooled models)

Diagnosis

# Check CPU load (1, 5, 15-minute averages)
cat /proc/loadavg
# Load > number of CPU cores = overloaded
# Pi 4/5 has 4 cores, so load > 4.0 means overloaded

# Find the CPU-hungry processes
top -o %CPU
# Or interactively with htop:
htop

# Check per-core usage
mpstat -P ALL 1 5

# Check if CPU is being throttled
vcgencmd get_throttled
# 0x0 = no throttling
# Bit meanings:
# 0: Under-voltage detected
# 1: Arm frequency capped
# 2: Currently throttled
# 3: Soft temperature limit active

Solutions

Kill runaway processes:

1
2
3
4
# Find and kill CPU-intensive process
ps aux --sort=-%cpu | head -5
kill -TERM <PID>    # Graceful termination
kill -KILL <PID>    # Force kill (if TERM doesn't work)

Disable unnecessary services:

# List services by resource usage
systemd-cgtop

# Disable services you don't need
sudo systemctl disable bluetooth    # If not using Bluetooth
sudo systemctl disable cups         # If not printing
sudo systemctl disable ModemManager # If not using mobile broadband
sudo systemctl disable triggerhappy # If not using hotkeys

# Check what's enabled
systemctl list-unit-files --state=enabled

Optimize CPU frequency:

1
2
3
4
5
6
7
8
# Check current frequency
vcgencmd measure_clock arm

# Set performance governor (max speed)
echo "performance" | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

# Or set conservative governor (save power)
echo "conservative" | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

See CPU Frequency Scaling and CPU Isolation and Task Affinity for advanced tuning.

Memory Troubleshooting

Symptoms

  • Applications crash unexpectedly
  • Killed messages in terminal
  • System becomes extremely slow then recovers
  • Desktop environment freezes

Diagnosis

# Check memory usage
free -h
# Key values:
# - "available" (not "free") = actual usable memory
# - If Swap "used" > 0, you're under memory pressure

# Check per-process memory usage
ps aux --sort=-%mem | head -10

# Check if OOM killer has been triggered
dmesg | grep -i "oom\|killed process"
sudo journalctl -k | grep -i "oom"

# Monitor memory in real-time
watch -n 1 free -h

# Check swap usage
swapon --show

Solutions

Reduce memory usage:

# Switch from Desktop to CLI (saves ~200MB RAM)
sudo raspi-config
# System Options → Boot/Auto Login → Console

# Reduce GPU memory allocation (Pi 4 and earlier under X11 only)
# Note: On Raspberry Pi 5 and Bookworm under Wayland, GPU memory is managed 
# dynamically by the system, so 'gpu_mem' is ignored and unnecessary.
sudo nano /boot/firmware/config.txt
# Set gpu_mem=16 for headless servers (minimum)
# Set gpu_mem=64 for light desktop use
# Set gpu_mem=128 for video playback (default)

Enable ZRAM swap:

Raspberry Pi OS Bookworm has ZRAM swap enabled by default, which automatically creates a compressed RAM-based swap space. You can verify its status with:

1
2
3
zramctl
# Or check the swap overview
swapon --show

To configure or customize ZRAM on Bookworm, we recommend using zram-generator (the modern Debian standard):

1
2
3
4
5
6
7
8
9
# Install zram-generator
sudo apt install systemd-zram-generator -y

# Configure it via /etc/systemd/zram-generator.conf
sudo nano /etc/systemd/zram-generator.conf
# Example configuration:
# [zram0]
# zram-size = ram / 2
# compression-algorithm = lz4

Note: The legacy SD card swap daemon dphys-swapfile is disabled or not installed by default on Bookworm. If present, disable it using:

sudo systemctl disable --now dphys-swapfile

See Optimizing Swap with ZRAM for detailed setup.

Find memory leaks:

1
2
3
4
5
6
7
8
9
# Monitor a specific process over time
pidstat -r -p $(pgrep process_name) 1

# If RSS (Resident Set Size) keeps growing, you have a leak
# Check RSS over 60 seconds:
for i in $(seq 1 60); do
  ps -o pid,rss,vsz,comm -p $(pgrep process_name) --no-headers
  sleep 1
done | tee /tmp/memlog.txt

Storage (I/O) Troubleshooting

Symptoms

  • Long pauses during file operations
  • High wa (I/O wait) in top
  • Programs slow to start
  • System hangs during writes

Diagnosis

# Check I/O wait percentage
top
# Look at %wa in the CPU line — anything > 10% indicates I/O bottleneck

# Real-time I/O monitoring per process
sudo iotop -o
# -o shows only processes doing I/O

# Check disk I/O statistics
iostat -x 1 5
# Key metrics:
# - r/s, w/s: reads/writes per second
# - await: average time per I/O (ms) — high = slow disk
# - %util: disk utilization — near 100% = saturated

# Check filesystem health
sudo dmesg | grep -i "error\|fail\|corrupt\|mmc"

# Benchmark your storage
sudo hdparm -Tt /dev/mmcblk0    # SD card
sudo hdparm -Tt /dev/sda        # USB drive

Solutions

Upgrade to SSD (biggest impact):

Upgrade Path Speed Improvement Guide
SD → USB SSD (Pi 4) 5-10× Move Rootfs to USB
SD → NVMe (Pi 5) 10-30× NVMe Boot on Pi 5

Optimize I/O without new hardware:

# Change I/O scheduler to deadline (better for SD cards)
echo "deadline" | sudo tee /sys/block/mmcblk0/queue/scheduler

# Reduce filesystem journaling overhead
sudo tune2fs -o journal_data_writeback /dev/mmcblk0p2

# Mount with noatime (reduces writes)
# Edit /etc/fstab: add noatime option

# Move write-heavy directories to RAM
# Add to /etc/fstab:
# tmpfs /tmp tmpfs defaults,noatime,nosuid,size=100M 0 0
# tmpfs /var/log tmpfs defaults,noatime,nosuid,size=50M 0 0

See I/O Scheduler Optimization for more details.

Thermal Troubleshooting

Symptoms

  • Performance drops during sustained workloads
  • Throttling indicator in vcgencmd
  • System becomes slow after running for a while
  • Random shutdowns (at 85°C+)

Diagnosis

# Check current temperature
vcgencmd measure_temp

# Monitor temperature continuously
watch -n 1 vcgencmd measure_temp

# Check throttling history
vcgencmd get_throttled
# Decode the hex value:
# Bit 0: Under-voltage detected
# Bit 1: Arm frequency capped
# Bit 2: Currently throttled
# Bit 3: Soft temperature limit active
# Bits 16-19: Same flags, but "has occurred since last reboot"

# Run a stress test and monitor
sudo apt install stress-ng
stress-ng --cpu 4 --timeout 120 &
watch -n 1 'vcgencmd measure_temp; vcgencmd measure_clock arm; vcgencmd get_throttled'

Solutions

Cooling solutions (from cheapest to best):

Solution Cost Temp Reduction Best For
Heat sinks only $2-5 -5 to -10°C Light workloads
Small fan + heat sinks $5-10 -15 to -25°C Most users
Official Active Cooler (Pi 5) $5 -20 to -30°C Pi 5 owners
ICE Tower cooler $15-25 -25 to -35°C Heavy workloads, overclocking
Argon ONE case (with fan) $25-45 -20 to -30°C Clean look + good cooling

Software thermal management:

# Set GPIO fan trigger temperature (only for custom/third-party GPIO fans)
# Note: Official Active Cooler on Raspberry Pi 5 and official cases with fans 
# are managed automatically by the OS. No configuration is required.
# For third-party fans, add to /boot/firmware/config.txt:
dtoverlay=gpio-fan,gpiopin=14,temp=60000
# Fan turns on at 60°C

# Reduce CPU load → reduce heat
# Underclock if you don't need full speed
# In /boot/firmware/config.txt:
arm_freq=1500   # Default is 1800 for Pi 5

See Temperature Monitoring and Alerts.

Network Troubleshooting

Symptoms

  • Web pages load slowly
  • SSH sessions lag
  • File transfers are slow
  • Intermittent disconnections

Diagnosis

# Check network interfaces
ip addr show

# Test latency
ping -c 10 8.8.8.8

# Test download speed
wget -O /dev/null http://speedtest.tele2.net/10MB.zip 2>&1 | tail -2

# Check for packet loss
ping -c 100 -i 0.1 192.168.1.1 | tail -3

# Check Wi-Fi signal strength
iwconfig wlan0
# Look for "Signal level" — closer to 0 = better
# -30 dBm = excellent, -67 dBm = good, -70 dBm = weak, -80 dBm = poor

# Check for network errors
ifconfig eth0 | grep -i "error\|drop"

# Monitor bandwidth usage
sudo apt install iftop
sudo iftop -i eth0

Solutions

Wi-Fi improvements:

1
2
3
4
5
6
7
8
9
# Disable power management (prevents disconnections)
sudo iwconfig wlan0 power off

# Make it persistent: create /etc/NetworkManager/conf.d/wifi-powersave.conf
echo -e "[connection]\nwifi.powersave = 2" | sudo tee /etc/NetworkManager/conf.d/wifi-powersave.conf

# Use 5GHz band if available (less interference)
# Check your Pi supports it:
iw list | grep "Band 2"

Ethernet improvements:

1
2
3
4
5
# Use wired Ethernet instead of Wi-Fi (always faster and more reliable)
# Check actual Ethernet speed
ethtool eth0 | grep Speed

# If showing 100Mbps instead of 1000Mbps, try a different cable

See Networking Setup and Management.

System-Level Diagnostics

Boot Time Analysis

1
2
3
4
5
6
7
8
# Check total boot time
systemd-analyze

# See which services are slowest
systemd-analyze blame | head -15

# Generate a boot chart (SVG)
systemd-analyze plot > boot-chart.svg

Finding Resource Hogs

# Top CPU consumers
ps aux --sort=-%cpu | head -10

# Top memory consumers
ps aux --sort=-%mem | head -10

# Top I/O consumers
sudo iotop -ob -n 5 | head -30

# Services consuming the most resources
systemd-cgtop -n 3

Creating a System Health Report

Save this as ~/health-check.sh:

#!/bin/bash
echo "========================================"
echo "  Raspberry Pi Health Check Report"
echo "  $(date)"
echo "========================================"
echo ""
echo "--- Temperature ---"
vcgencmd measure_temp
echo ""
echo "--- Throttling ---"
THROTTLED=$(vcgencmd get_throttled | cut -d= -f2)
if [ "$THROTTLED" = "0x0" ]; then
    echo "No throttling detected ✅"
else
    echo "Throttling detected: $THROTTLED ⚠️"
fi
echo ""
echo "--- CPU ---"
echo "Load average: $(cat /proc/loadavg | awk '{print $1, $2, $3}')"
echo "Frequency: $(vcgencmd measure_clock arm | awk -F= '{printf "%.0f MHz\n", $2/1000000}')"
echo ""
echo "--- Memory ---"
free -h | grep -E "Mem:|Swap:"
echo ""
echo "--- Disk ---"
df -h / | tail -1 | awk '{print "Used:", $3, "/", $2, "(" $5 ")"}'
echo ""
echo "--- Top Processes (CPU) ---"
ps aux --sort=-%cpu | head -6 | tail -5
echo ""
echo "--- Top Processes (Memory) ---"
ps aux --sort=-%mem | head -6 | tail -5
echo ""
echo "--- Uptime ---"
uptime -p
echo "========================================"
chmod +x ~/health-check.sh
./health-check.sh

Performance Optimization Checklist

Use this checklist to ensure your Pi is running optimally:

  • Power supply is adequate (no under-voltage warnings)
  • Cooling is sufficient (temperature stays below 70°C under load)
  • Storage is fast enough (SSD recommended for servers)
  • Unused services are disabled
  • GPU memory is set appropriately (16MB for headless, 128MB for desktop)
  • ZRAM is enabled (instead of SD card swap)
  • System is updated (sudo apt update && sudo apt full-upgrade)
  • Filesystem is healthy (no errors in dmesg)
  • Network is using wired Ethernet for servers (not Wi-Fi)
  • Logs are rotated and size-limited