STORAGE ENGINEERING

TRIM & discard configuration on Linux

Category: SSD MaintenanceTechnologies: fstrim, blkdiscard, nvme format, dm-crypt, LVM thin pools, Btrfs async discard

TRIM informs SSDs and NVMe drives which blocks are no longer in use, allowing the garbage collector to proactively erase them. Without TRIM, the drive doesn't know which blocks contain deleted data, leading to write amplification and performance degradation over time.

How TRIM works

Flash memory is organized in pages (typically 4-16 KiB) that can be written individually but must be erased in blocks (typically 128-512 pages). The erase-before-write cycle causes write amplification: writing 4 KiB may require reading, erasing, and rewriting an entire 4 MiB block.

TRIM solves this by telling the drive which pages are free, so garbage collection can erase them ahead of time:

fstrim (periodic batch TRIM, recommended)

# Trim a specific mounted filesystem
fstrim -v /

# Trim all mounted filesystems that support it
fstrim --all -v

# Trim with offset and length
fstrim -o 10G -l 50G /mnt/data

# Minimum extent size to trim
fstrim -m 64M /mnt/data

fstrim.timer (systemd weekly timer)

# Enable weekly TRIM
sudo systemctl enable --now fstrim.timer

# Check status
systemctl status fstrim.timer

# View timer configuration
systemctl cat fstrim.timer

The default timer runs weekly with a randomized delay. This is the recommended approach, Red Hat, Debian, Arch Wiki, and Ubuntu (enabled by default since 18.04) all recommend periodic fstrim over continuous discard.

discard mount option (continuous TRIM)

# Mount with continuous discard
mount -o discard /dev/sdb1 /mnt/data

# In /etc/fstab
/dev/sdb1 /mnt/data ext4 defaults,discard 0 1
Continuous discard is generally NOT recommended

With discard, every file deletion triggers a TRIM command, causing latency spikes on some devices. Samsung 840/850 series and some other SSDs have known performance issues with continuous discard. XFS documentation specifically recommends against it. Use periodic fstrim instead.

Filesystem support

Filesystemdiscard mount optionperiodic fstrimNotes
ext4YesYesDefault: nodiscard (periodic recommended)
XFSYesYesDocs recommend against continuous discard
BtrfsYesYesdiscard=async since kernel 5.6 (default since 6.2)
F2FSYesYes-
NTFS (ntfs3)YesYesNTFS-3G supports periodic only
Swap--TRIM with swap + discard option or swapon -d

Btrfs async discard

Since kernel 5.6, Btrfs supports discard=async, which moves TRIM out of the transaction commit path and rate-limits the discard I/O. This eliminates the latency penalty of synchronous discard while still reclaiming space promptly. It is the default since kernel 6.2 when the device supports it.

# Explicit async discard
mount -o discard=async /dev/sdb1 /mnt

# Synchronous (legacy behavior)
mount -o discard=sync /dev/sdb1 /mnt

blkdiscard (whole-device TRIM)

# Discard entire device (DESTROYS ALL DATA)
blkdiscard /dev/sdX

# Discard a range
blkdiscard -o 10G -l 50G /dev/sdX

# Secure discard (if supported)
blkdiscard -s /dev/sdX

# Zero-fill discard (write zeroes to discarded blocks, if supported)
blkdiscard -z /dev/sdX

Use cases: wiping an SSD before repartitioning, returning space to thin-provisioned storage. Note that TRIM doesn't guarantee immediate erasure. The SSD controller decides when to erase blocks.

NVMe format (secure erase)

# User data erase
nvme format /dev/nvme0n1 --ses=1

# Cryptographic erase (delete encryption key)
nvme format /dev/nvme0n1 --ses=2

# Format specific namespace
nvme format /dev/nvme0 --namespace-id=1 --ses=1

# Check if crypto-erase is supported
nvme id-ctrl /dev/nvme0 | grep fna
ses valueAction
0No secure erase (default)
1User data erase: all data erased, contents indeterminate
2Cryptographic erase: delete encryption key, data becomes unreadable

RAID and TRIM

mdadm

Since kernel 3.7, md supports TRIM for linear, RAID 0, RAID 1, RAID 5, and RAID 10. RAID 1 is safe, both mirrors receive the same TRIM. RAID 5/6 requires a kernel parameter because drives must return zeroes on discarded regions:

# Kernel command line for RAID 5/6 TRIM
raid456.devices_handle_discards_safely=y

# Test before enabling in production
cat /sys/block/md0/md/mismatch_cnt
mdadm --action=check /dev/md0 && mdadm --wait /dev/md0
fstrim -v /
mdadm --action=check /dev/md0 && mdadm --wait /dev/md0
cat /sys/block/md0/md/mismatch_cnt   # should still be 0

dm-crypt and TRIM

# Enable discard on LUKS mapping
cryptsetup --allow-discards open /dev/sdb1 crypt

# Refresh an existing mapping
cryptsetup refresh --allow-discards crypt
Security implications of dm-crypt TRIM

Enabling allow_discards can leak information about the ciphertext device: which blocks are used vs. free, which can reveal the filesystem type and data patterns. Default is disabled for security. Assess the trade-off carefully, for most desktop/laptop use cases the leak is acceptable; for plausible-deniability setups it is not.

LVM thin pools and TRIM

LVM thin pools can pass discard commands through to underlying devices. Three modes control this:

ModeBehavior
ignoreDiscards are dropped, no space reclamation
nopassdownDiscards free chunks within the thin pool but are not passed to the underlying device
passdown (default)Discards free chunks in the pool AND pass through to the underlying device
# Set discard mode when creating a thin pool
lvconvert --type thin-pool --discards passdown \
  --poolmetadata VG/ThinMetaLV VG/ThinDataLV

# Change mode of existing thin pool
lvchange --discards passdown VG/ThinPoolLV

# Display current mode
lvs -o+discards VG/ThinPoolLV

Note: thin snapshots keep chunks from being freed, so fstrim on a thin LV with snapshots may not reclaim as much space as expected.

Recommendation summary

  1. Use periodic fstrim (weekly timer). This is the universal recommendation.
  2. Avoid the continuous discard mount option except on Btrfs with discard=async.
  3. Enable allow_discards on dm-crypt if the security trade-off is acceptable for your threat model.
  4. Use --discards passdown on LVM thin pools to reclaim space on underlying devices.
  5. Test RAID 5/6 TRIM with mismatch_cnt before enabling it in production.
  6. Use blkdiscard or nvme format when repurposing or disposing of drives.