Monitor Raspberry Pi Performance
Monitor your Raspberry Pi's CPU, memory, temperature, and disk usage. Covers htop, vcgencmd, Netdata, and Prometheus.
Introduction
Keeping tabs on your Raspberry Pi's health is essential for stability and performance, especially in remote deployments. This guide covers essential monitoring tools—from built-in commands to full stacks like Prometheus and Grafana—so you can track CPU, memory, temperature, and disk usage in real-time.
Prerequisites
- Raspberry Pi 3B+ or newer
- SSH access or terminal
- Optional: Docker for advanced monitoring stacks
Step 1 — Quick System Checks with Built-in Tools
Start with commands already on your Pi. These give you instant insight without additional setup:
# Check CPU temperature
vcgencmd measure_temp
# Display memory usage
free -h
# Check disk usage
df -h
# Check system uptime and load average
uptime
Run these commands to establish a baseline. Temperature above 70°C indicates throttling risk on Pi 4/5.
Step 2 — Real-Time Process Monitoring with htop
Install htop for interactive process viewing:
sudo apt install htop -y
htop
Navigate with arrow keys, press T to sort by memory, P for CPU. Press q to exit. htop shows per-core usage clearly—useful for spotting single-threaded bottlenecks.
Step 3 — Install Netdata for Web Dashboard
Netdata offers a lightweight (~100MB RAM), real-time web UI. Install with one command:
wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh
sh /tmp/netdata-kickstart.sh --stable-channel --disable-telemetry
Access the dashboard at http://your-pi-ip:19999. Netdata tracks CPU, memory, disk I/O, network, and temperature automatically. No configuration needed.
Step 4 — Advanced Stack: Prometheus + Node Exporter + Grafana
For persistent historical data, set up Prometheus:
# Create monitoring directory
mkdir -p ~/monitoring && cd ~/monitoring
# Create docker-compose.yml
cat > docker-compose.yml <<'EOF'
version: '3.8'
services:
node-exporter:
image: arm32v6/node-exporter:latest
container_name: node-exporter
restart: always
ports:
- "9100:9100"
volumes:
- /:/rootfs:ro
- /sys:/sys:ro
- /proc:/proc:ro
command:
- '--path.rootfs=/rootfs'
- '--path.sysfs=/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
prometheus:
image: arm32v6/prometheus:latest
container_name: prometheus
restart: always
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: always
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
volumes:
prometheus_data:
grafana_data:
EOF
# Create prometheus.yml
cat > prometheus.yml <<'EOF'
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
EOF
# Start services
docker-compose up -d
Access Grafana at http://your-pi-ip:3000 (default: admin/admin). Add Prometheus data source at http://localhost:9090, then import dashboard ID 1860 for Node Exporter metrics.
Step 5 — Custom Telegram Alert Script
Alert when temperature exceeds 70°C:
cat > ~/temp-alert.sh <<'EOF'
#!/bin/bash
TELEGRAM_TOKEN="your-bot-token"
TELEGRAM_CHAT_ID="your-chat-id"
THRESHOLD=70
while true; do
TEMP=$(vcgencmd measure_temp | grep -oP '\d+\.\d+')
TEMP_INT=${TEMP%.*}
if [ "$TEMP_INT" -gt "$THRESHOLD" ]; then
curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage" \
-d "chat_id=$TELEGRAM_CHAT_ID" \
-d "text=Alert: Pi temperature is ${TEMP}°C"
fi
sleep 300 # Check every 5 minutes
done
EOF
chmod +x ~/temp-alert.sh
nohup ~/temp-alert.sh > /tmp/temp-alert.log 2>&1 &
Replace your-bot-token and your-chat-id with actual values from BotFather and your Telegram account.
Monitoring Tools Comparison
| Tool | Memory | CPU | Real-Time | Historical | Web UI |
|---|---|---|---|---|---|
| Built-in (vcgencmd) | <5MB | minimal | yes | no | no |
| htop | ~10MB | minimal | yes | no | no |
| Netdata | 100MB | 2-3% | yes | 24h default | yes |
| Prometheus | 150-200MB | 3-5% | yes | 30+ days | yes (Grafana) |
Troubleshooting
High memory usage despite low workload
Netdata and Prometheus grow over time. Reduce retention: edit docker-compose and lower storage.tsdb.retention.time to 7d or restart services to clear old data.
Temperature alerts firing too often
Increase THRESHOLD in the alert script or extend the sleep interval to 600 seconds (10 minutes) for less noise.
Grafana dashboard not updating
Verify Node Exporter is running: curl http://localhost:9100/metrics | head -20. Restart Prometheus if metrics are stale.
Port already in use
If port 9090 is occupied, change Prometheus port: edit docker-compose to "9091:9090" and update Grafana data source accordingly.
Summary
Use built-in tools for quick health checks, Netdata for a lightweight dashboard, and Prometheus/Grafana for production monitoring with alerting. Most homelabs thrive on Netdata alone—only reach for the full stack if you need historical analysis or multi-Pi federation.