SSD Optimization on Ubuntu

SSDs differ from HDDs in ways that require specific Linux configuration to get full performance and longevity. The key differences: SSDs wear out based on write cycles, they benefit from TRIM to maintain performance over time, and they do not need defragmentation. Ubuntu handles most SSD optimization automatically since 12.04, but there are still several settings worth verifying and tuning on production servers.

Why SSD optimization matters

IssueWithout optimizationWith optimization
TRIMPerformance degrades over time as SSD manages dirty blocksConsistent performance as OS signals deleted blocks
Access timeatime updates cause unnecessary writes on readsnoatime removes write amplification from reads
SwapHigh swap activity wears flash cellsLow swappiness reduces SSD wear
I/O schedulerElevator scheduler wastes time reordering requests (helps HDD, not SSD)mq-deadline or none: minimal overhead for SSD

TRIM configuration

TRIM tells the SSD which blocks are no longer in use (deleted), so the SSD’s controller can erase them in advance, maintaining write performance and extending drive life.

# Check if TRIM is supported by the SSD
sudo hdparm -I /dev/sda | grep -i trim    # SATA SSD
sudo nvme id-ctrl /dev/nvme0n1 | grep -i "dsm"  # NVMe: DSM = Dataset Management = TRIM

# Method 1: Continuous TRIM (discard mount option)
# In /etc/fstab, add 'discard':
UUID=...  /  ext4  defaults,noatime,discard  0  1
# Downside: small performance impact on every delete; can cause write amplification
# Method 2: Periodic TRIM (recommended for most setups)
# Ubuntu enables fstrim.timer by default since 20.04
sudo systemctl status fstrim.timer

fstrim.timer status

fstrim.timer - Discard unused blocks once a week
  Loaded: loaded (/lib/systemd/system/fstrim.timer; enabled)
  Active: active (waiting)
 Trigger: Mon 2024-06-10 00:00:00 UTC
# Run TRIM manually
sudo fstrim -v /

# Enable fstrim.timer if not already active
sudo systemctl enable --now fstrim.timer

Mount options for SSDs

# Recommended /etc/fstab options for SSD partitions:
# noatime: don't update file access time on reads (saves writes)
# nodiratime: don't update directory access time
# discard: continuous TRIM (or use fstrim.timer instead)

# Example /etc/fstab entry for SSD root partition:
UUID=abc123...  /       ext4   defaults,noatime          0  1
UUID=def456...  /home   ext4   defaults,noatime          0  2
UUID=ghi789...  /data   xfs    defaults,noatime          0  2

# Apply without reboot:
sudo mount -o remount,noatime /
sudo mount -o remount,noatime /home

I/O scheduler for SSDs

# Check current I/O scheduler
cat /sys/block/sda/queue/scheduler    # SATA SSD
cat /sys/block/nvme0n1/queue/scheduler  # NVMe

Scheduler output for SATA SSD

[mq-deadline] kyber bfq none
# mq-deadline is the default for SATA SSDs — appropriate
# Change scheduler temporarily (for testing)
echo mq-deadline | sudo tee /sys/block/sda/queue/scheduler

# Make permanent with udev rule
cat > /etc/udev/rules.d/60-ioschedulers.rules << 'EOF'
# NVMe: use none scheduler
ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
# SSD: use mq-deadline
ACTION=="add|change", KERNEL=="sd[a-z]|mmcblk[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"
# HDD: use bfq
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
EOF
sudo udevadm control --reload-rules && sudo udevadm trigger

Reducing writes to extend SSD life

# Move /tmp to tmpfs (RAM) — eliminates tmp file writes to SSD
# Add to /etc/fstab:
tmpfs  /tmp      tmpfs  defaults,nosuid,nodev,noexec  0  0
tmpfs  /var/tmp  tmpfs  defaults,nosuid,nodev,noexec  0  0

# Reduce swappiness (reduces SSD swap writes)
echo "vm.swappiness=10" | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl -p /etc/sysctl.d/99-swappiness.conf

# Move browser/application caches to tmpfs (for desktop SSDs)
# This is less relevant for servers

Checking SSD health

# SATA SSD health check with smartctl
sudo apt install -y smartmontools
sudo smartctl -a /dev/sda | grep -E "Wear_Leveling|Total_LBAs|Available_Reservd"

# Key SMART attributes for SSDs:
# 177: Wear Leveling Count — how many erase cycles
# 160: Uncorrectable Sector Count — should be 0
# 232: Available Reserved Space — % spare blocks left

# NVMe health
sudo apt install -y nvme-cli
sudo nvme smart-log /dev/nvme0n1 | grep -E "percentage_used|available_spare"

# Set up SMART monitoring daemon
sudo systemctl enable smartd
sudo systemctl start smartd

Conclusion

The three most impactful SSD optimizations on Ubuntu: add noatime to all fstab entries to eliminate unnecessary writes on reads, ensure fstrim.timer is running for weekly TRIM, and set swappiness to 10 to reduce swap writes to SSD. Ubuntu handles most SSD optimization automatically (scheduler, TRIM timer), so you mainly need to verify these settings and add noatime. Monitor SSD wear with smartctl or nvme smart-log and plan for replacement when available spare space drops below 10%.

FAQ

Is SSD Optimization important for Ubuntu administrators?+

Yes. It supports practical Ubuntu administration because it connects directly to server reliability, security, troubleshooting, or daily operations.

Should I practice this on a live server?+

Use a lab VM first. After you understand the command output and rollback path, apply the workflow carefully on real systems.

What should I do after reading this article?+

Run the practice commands, write down what each one shows, and continue to the next article in the Ubuntu roadmap.

Need help with Ubuntu administration?

Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.

Hire Me for Support