Optimize SD Card Performance

Speed up your Raspberry Pi by optimizing SD card performance. Covers filesystem tuning, swap, log reduction, and SSD migration.

Andreas · April 12, 2026 · 7 min read

Introduction

SD card wear and slow write speeds are common problems in Raspberry Pi deployments. SD cards use flash memory with limited write cycles (typically 10,000+ writes to the same block before failure). By tuning the filesystem, reducing writes, and offloading heavy IO to USB SSDs, you can dramatically extend SD card lifespan and improve responsiveness.

Why SD Cards Fail

SD cards use MLC/TLC NAND flash. Each cell tolerates ~1,000-10,000 full write cycles before degradation. When the filesystem writes frequently (logs, temporary files, Docker container data), wear accumulates fast. Write amplification multiplies this: a single logical write can trigger multiple physical writes inside the card's controller. A journaling filesystem (ext4) adds extra writes for metadata.

A typical failure sequence: months of normal operation, then sudden corruption as worn cells go bad. Preemption: reduce writes by 50-90%, and your SD card lives 5-10x longer.

Benchmarking Before Changes

Install and run fio to baseline your current performance:

sudo apt install fio -y

Baseline sequential write speed:

fio --name=seq_write --rw=write --bs=1m --size=1g --numjobs=1 --ioengine=libaio --iodepth=4 --direct=1 --filename=/mnt/test_file

Expected baseline: SD cards typically write at 20-40 MB/s. USB 3 SSDs: 200-500 MB/s.

Sequential read (should be faster):

fio --name=seq_read --rw=read --bs=1m --size=1g --numjobs=1 --ioengine=libaio --iodepth=4 --direct=1 --filename=/mnt/test_file

Keep these numbers to compare after optimizations. A 2x read speedup and 3x write improvement is typical with the changes below.

Step 1 — Reduce Logging to RAM (log2ram)

Logs are the biggest write culprit. log2ram redirects /var/log to a RAM disk, syncing to SD card hourly instead of every write.

Install:

curl -sSL https://azlux.fr/install.sh | sudo bash

Configure /etc/log2ram.conf:

SIZE=256M
MAIL=false
ENABLE=true
SYNC_INTERVAL=60

Size depends on your logging volume. Start with 256M.

Enable and start:

sudo systemctl enable log2ram
sudo systemctl start log2ram

Verify:

df -h | grep log2ram

Benefit: Reduces filesystem writes by 30-50% immediately.

Step 2 — Disable Swap (or Move to USB SSD)

Swap writes to disk constantly. If you have 2GB+ RAM, disable it:

sudo dphys-swapfile swapoff
sudo dphys-swapfile uninstall
sudo systemctl disable dphys-swapfile

If you need swap, move it to USB SSD instead:

# Assuming USB SSD is /dev/sda1, mounted at /mnt/ssd
sudo mkdir -p /mnt/ssd/swapfile
sudo fallocate -l 2G /mnt/ssd/swapfile
sudo chmod 600 /mnt/ssd/swapfile
sudo mkswap /mnt/ssd/swapfile
sudo swapon /mnt/ssd/swapfile

Add to /etc/fstab:

/mnt/ssd/swapfile none swap sw 0 0

Step 3 — Filesystem Tuning (ext4)

Mount / with noatime (skip access time updates) and longer commit intervals:

Current mount options:

mount | grep " / "

Edit /etc/fstab and modify the root line:

PARTUUID=abcdef /  ext4  defaults,noatime,commit=60 0  1
  • noatime — Don't update file access times (saves ~10% writes)
  • commit=60 — Sync filesystem every 60 seconds instead of 5 (batches writes, speeds up everyday operations)

Apply changes (requires reboot):

sudo reboot

Verify:

mount | grep " / " | tr ',' '\n' | grep -E 'noatime|commit'

Step 4 — Move /tmp and Docker Data to USB SSD

Temporary and container data should live on fast storage:

Create SSD mount point:

sudo mkdir -p /mnt/ssd
sudo mount /dev/sda1 /mnt/ssd  # Adjust device path

Move Docker data:

sudo systemctl stop docker
sudo mv /var/lib/docker /mnt/ssd/docker
sudo ln -s /mnt/ssd/docker /var/lib/docker
sudo systemctl start docker

Redirect /tmp to SSD:

sudo mount --bind /mnt/ssd/tmp /tmp

Add to /etc/fstab for persistence:

/mnt/ssd/tmp /tmp none bind,defaults 0 0

Step 5 — Consider Booting from USB SSD

The ultimate optimization: keep only bootloader and kernel on SD card, run everything else from SSD.

Update Pi firmware to support USB boot:

sudo rpi-update

On a fresh SSD, clone your SD card or do a fresh Raspberry Pi OS install on the SSD. Then modify /boot/firmware/config.txt:

[pi4]
boot_order=0xf21
# 1=USB, 2=SD, f=retry

This tries USB boot first, falls back to SD. No more SD card wear from app execution.

Benchmark Comparison

Operation Baseline (SD) After Tuning (SD) USB SSD
Sequential write 25 MB/s 30 MB/s 350 MB/s
Seq read 85 MB/s 85 MB/s 450 MB/s
Random 4K write 2 MB/s 2.5 MB/s 120 MB/s
Total daily writes (untuned app) 5 GB 1.5 GB 1.5 GB

The tuning cuts writes 3-4x. Adding USB SSD boot cuts them further. Combined, a Pi runs 10x longer without SD corruption.

Monitoring Disk Health

Check ext4 filesystem status:

sudo tune2fs -l /dev/mmcblk0p2 | grep -i 'mount\|error'

Monitor inode usage (when full, filesystem gets slow):

df -i /

Watch for Used % creeping above 80%. If it does, prune old logs or move applications.

Troubleshooting

Can't mount /tmp bindmount --bind requires /mnt/ssd/tmp to exist first: sudo mkdir -p /mnt/ssd/tmp.

Docker won't start after moving — Verify symlink: ls -la /var/lib/docker. If it's missing, recreate it: sudo ln -s /mnt/ssd/docker /var/lib/docker.

System slow after noatime — This is normal if you depend on mtime for backups. Add relatime instead: relatime,commit=60 (updates atime on access, batched writes).

log2ram running out of space — Logs are piling up. Increase SIZE in /etc/log2ram.conf or lower application log levels (disable DEBUG in production).

Summary

Optimizing SD card performance starts with reducing writes: log2ram, noatime, and longer commit intervals give immediate wins. Moving heavy IO (swap, Docker, /tmp) to USB SSD extends card lifespan dramatically. For critical systems, boot from SSD entirely. With these techniques, an SD card lasts years instead of months.

Related Tools

Comments