The server was slow at 2:17 PM. By the time you get the call it is 3:45 PM and everything looks fine. Without historical data you are guessing. With sar (System Activity Reporter) you can go back in time and see exactly what the CPU, memory, disk, and network were doing at 2:17 PM — even days or weeks ago.
sysstat is the package that
provides sar, iostat, mpstat, and
pidstat. It runs a data collection daemon (sadc)
every 10 minutes by default, storing performance snapshots that sar can
replay on demand. Install it on every server you manage — you will
need it eventually.
# Install sysstat sudo dnf install -y sysstat # RHEL/Rocky sudo apt install -y sysstat # Debian/Ubuntu # Enable data collection sudo systemctl enable --now sysstat # On Debian/Ubuntu -- also enable in the config file sudo vi /etc/default/sysstat # Set: ENABLED="true" sudo systemctl restart sysstat # Verify it is running and collecting sudo systemctl status sysstat ls -la /var/log/sa/ # Data files are stored as /var/log/sa/saDD (DD = day of month) # sadc collects data every 10 minutes by default ls -lh /var/log/sa/ls /var/log/sa/ output:
# Show today's CPU activity (all samples) sar # CPU activity for today in real time (2 second intervals) sar 2 10 # CPU activity from yesterday's data file sar -f /var/log/sa/sa25 # CPU activity for a specific time range today sar -s 14:00:00 -e 15:00:00 # Per-CPU statistics (all cores) sar -P ALL # Show specific CPU core sar -P 0 # CPU 0 onlysar output:
# Memory statistics sar -r # Memory for a time range sar -r -s 14:00:00 -e 15:00:00 # Swap statistics sar -S # Memory and swap from previous day sar -r -f /var/log/sa/sa25 sar -S -f /var/log/sa/sa25 # Huge pages sar -Hsar -r output (key columns):
kbavail dropping to near zero means the system was running
out of usable memory. %commit over 100% means the system
has committed more virtual memory than physically exists — a sign
of memory overcommit that leads to OOM kills.
# Disk I/O statistics sar -d # With human-readable device names sar -d -p # Disk I/O for a time range sar -d -p -s 14:00:00 -e 15:00:00 # Block device statistics from previous day sar -d -p -f /var/log/sa/sa25sar -d -p output:
# Network interface statistics sar -n DEV # Network errors sar -n EDEV # TCP statistics sar -n TCP # TCP errors sar -n ETCP # All network stats sar -n ALL # Network stats for a time range sar -n DEV -s 14:00:00 -e 15:00:00sar -n DEV output:
# mpstat -- per-CPU statistics in real time mpstat 2 5 # all CPUs, 2 second intervals mpstat -P ALL 2 5 # show each CPU individually mpstat -P 0,1 2 5 # show CPU 0 and 1 only # pidstat -- per-process CPU and I/O statistics pidstat 2 5 # CPU stats for all active processes pidstat -r 2 5 # memory stats pidstat -d 2 5 # disk I/O stats per process pidstat -u -r -d 2 5 # CPU + memory + disk combined # pidstat for a specific process pidstat -p 12345 2 5 # pidstat for processes matching a name pidstat -C nginx 2 5pidstat -d output (disk I/O per process):
# Default collection is every 10 minutes # Check the cron/timer configuration cat /etc/cron.d/sysstat # RHEL systemctl cat sysstat # systemd timer # RHEL cron config -- /etc/cron.d/sysstat cat /etc/cron.d/sysstat/etc/cron.d/sysstat:
# Change to every 5 minutes for higher resolution sudo vi /etc/cron.d/sysstat # Change */10 to */5 # How long are data files kept? grep HISTORY /etc/sysstat/sysstat 2>/dev/null || grep HISTORY /etc/sysconfig/sysstat # Extend history to 60 days (default is 7 or 28) sudo vi /etc/sysstat/sysstat # Set: HISTORY=60 # Manually collect a data point right now sudo /usr/lib64/sa/sa1 1 1 # RHEL path sudo /usr/lib/sysstat/sa1 1 1 # Debian path
#!/bin/bash # sar-investigate.sh -- pull sar data for a specific time window # Usage: ./sar-investigate.sh 2026-04-25 14:00 15:00 DATE=$1 # YYYY-MM-DD START=$2 # HH:MM END=$3 # HH:MM if [[ -z "$DATE" || -z "$START" || -z "$END" ]]; then echo "Usage: $0 YYYY-MM-DD HH:MM HH:MM" echo "Example: $0 2026-04-25 14:00 15:00" exit 1 fi # Convert date to day-of-month for sa file DAY=$(date -d "$DATE" +%d) SAFILE="/var/log/sa/sa$DAY" if [[ ! -f "$SAFILE" ]]; then echo "No sar data found for $DATE (looked for $SAFILE)" exit 1 fi echo "========================================" echo " SAR Investigation: $DATE $START - $END" echo "========================================" echo "" echo "--- CPU ---" sar -f "$SAFILE" -s "${START}:00" -e "${END}:00" echo "" echo "--- MEMORY ---" sar -r -f "$SAFILE" -s "${START}:00" -e "${END}:00" echo "" echo "--- DISK I/O ---" sar -d -p -f "$SAFILE" -s "${START}:00" -e "${END}:00" echo "" echo "--- NETWORK ---" sar -n DEV -f "$SAFILE" -s "${START}:00" -e "${END}:00" echo "" echo "--- LOAD AVERAGE ---" sar -q -f "$SAFILE" -s "${START}:00" -e "${END}:00" echo "========================================"
| Command | What it shows |
|---|---|
| sar | Today's CPU activity (all samples) |
| sar 2 10 | CPU activity live, 2-second intervals |
| sar -s 14:00 -e 15:00 | CPU activity for a time range today |
| sar -f /var/log/sa/sa25 | CPU from day 25's data file |
| sar -r | Memory statistics |
| sar -S | Swap statistics |
| sar -d -p | Disk I/O with device names |
| sar -n DEV | Network interface statistics |
| sar -n EDEV | Network errors |
| sar -n TCP | TCP statistics |
| sar -q | Load average and run queue |
| sar -P ALL | Per-CPU statistics |
| mpstat -P ALL 2 5 | Real-time per-CPU statistics |
| pidstat -d 2 5 | Disk I/O per process |
| pidstat -C nginx 2 5 | Stats for processes named nginx |