TRIM & discard configuration on Linux
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:
- ATA TRIM: SATA SSDs use the TRIM command (ATA standard)
- NVMe Dataset Management: NVMe uses the DSM command for the same purpose
- SCSI UNMAP: SCSI/SAS drives use UNMAP
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/datafstrim.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.timerThe 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 1With 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
| Filesystem | discard mount option | periodic fstrim | Notes |
|---|---|---|---|
| ext4 | Yes | Yes | Default: nodiscard (periodic recommended) |
| XFS | Yes | Yes | Docs recommend against continuous discard |
| Btrfs | Yes | Yes | discard=async since kernel 5.6 (default since 6.2) |
| F2FS | Yes | Yes | - |
| NTFS (ntfs3) | Yes | Yes | NTFS-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 /mntblkdiscard (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/sdXUse 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 value | Action |
|---|---|
| 0 | No secure erase (default) |
| 1 | User data erase: all data erased, contents indeterminate |
| 2 | Cryptographic 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 0dm-crypt and TRIM
# Enable discard on LUKS mapping
cryptsetup --allow-discards open /dev/sdb1 crypt
# Refresh an existing mapping
cryptsetup refresh --allow-discards cryptEnabling 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:
| Mode | Behavior |
|---|---|
ignore | Discards are dropped, no space reclamation |
nopassdown | Discards 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/ThinPoolLVNote: 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
- Use periodic
fstrim(weekly timer). This is the universal recommendation. - Avoid the continuous
discardmount option except on Btrfs withdiscard=async. - Enable
allow_discardson dm-crypt if the security trade-off is acceptable for your threat model. - Use
--discards passdownon LVM thin pools to reclaim space on underlying devices. - Test RAID 5/6 TRIM with
mismatch_cntbefore enabling it in production. - Use
blkdiscardornvme formatwhen repurposing or disposing of drives.