How Do You Use TRIM on EC2 SSD Instance Store Volumes?
Maintaining consistent write performance on solid-state drive backed Amazon EC2 instance store volumes requires informing the underlying storage hardware when data blocks are no longer in use. This article explains how the TRIM command and file system discard operations work on EC2 SSD instance store volumes, how to verify instance and operating system support, and how to configure periodic or continuous TRIM using tools like fstrim, blkdiscard, and mount options to prevent write amplification and throughput degradation.
Understanding SSD Write Performance and Write Amplification
Solid-state drives store data in flash memory cells organized into pages and blocks. While an SSD can read and write data at the page level (typically 4 KB to 16 KB), it can only erase data at the much larger block level (often 128 to 512 pages). Furthermore, flash memory pages cannot be overwritten directly in place; the existing data must be erased before new data can be written to the same physical location.
When you delete a file in your operating system, the file system only marks the corresponding logical blocks as free in its internal metadata tables. The underlying SSD controller has no intrinsic visibility into file system structures and continues to treat those physical pages as containing valid data. As the volume fills up with writes and deletions over time, the SSD controller runs out of pre-erased free blocks. To satisfy new write requests, the drive must perform internal garbage collection, reading valid pages out of a partially used block, writing them to a new location, and erasing the old block before writing the new data.
This phenomenon is known as write amplification. The write amplification factor (\(WAF\)) is expressed mathematically as:
\[WAF = \frac{\text{Bytes Written to Flash Memory}}{\text{Bytes Written by the Host OS}}\]
Without a mechanism to notify the SSD controller about deleted
blocks, \(WAF\) increases significantly
as the drive approaches capacity, causing higher write latency and lower
I/O operations per second (IOPS). The TRIM command (known as
UNMAP in SCSI and
Dataset Management Deallocate in NVMe) solves this problem
by allowing the operating system to explicitly notify the SSD controller
which data blocks are no longer needed. Once informed, the SSD
controller can skip copying stale pages during garbage collection and
erase blocks proactively during idle periods.
Checking TRIM Support on EC2 Instance Store Volumes
Most modern Amazon EC2 instance families with SSD-backed instance
store volumes—including NVMe-based instance stores (such as
i3, i3en, i4i, c5d,
m5d, and r5d) and older Xen-based SSD
instances with hardware TRIM support—support discard operations.
However, before running TRIM commands, you should verify that your
specific Linux kernel and block device expose discard capabilities.
You can check whether your instance store block devices support TRIM
by running the lsblk --discard command:
lsblk --discardLook at the DISC-GRAN (discard granularity) and
DISC-MAX (discard maximum bytes) columns in the output:
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
nvme0n1 0 512B 2T 0
└─nvme0n1p1 0 512B 2T 0
nvme1n1 0 4K 2T 0
If DISC-GRAN and DISC-MAX show non-zero
values (such as 512B or 4K for granularity,
and 2T or 4G for maximum bytes), the block
device supports TRIM operations. If both values are 0B, the
volume or virtualization layer does not support discard commands.
Performing a Full Volume TRIM Before Formatting
When an EC2 instance launches, or before you repurpose an existing SSD instance store volume, issuing a full-device discard ensures that the SSD controller knows all blocks are free prior to creating a file system or RAID array.
Using blkdiscard
For unmounted raw block devices, the blkdiscard utility
discards all sectors on the drive. Be cautious, as this operation
irreversibly destroys all existing data on the specified device:
sudo blkdiscard /dev/nvme1n1Formatting with mkfs
Many file system creation utilities automatically send TRIM commands
across the entire device during formatting. For ext4,
mkfs.ext4 enables discard by default. For XFS,
mkfs.xfs also performs a discard by default. If you want to
explicitly ensure discard occurs during formatting, or alternatively
skip it if you have already run blkdiscard, you can pass
specific flags:
# Explicitly enable discard during ext4 formatting
sudo mkfs.ext4 -E discard /dev/nvme1n1
# Explicitly enable discard during XFS formatting (default behavior)
sudo mkfs.xfs /f /dev/nvme1n1Method 1: Periodic TRIM with fstrim (Recommended)
For mounted file systems in production, running periodic batch TRIM operations is generally preferred over continuous TRIM. Periodic TRIM runs a scheduled job (typically weekly or daily) that scans the file system for all currently unallocated blocks and passes them to the SSD controller in large batches, minimizing impact on foreground I/O latency.
Running fstrim Manually
You can trigger an on-demand TRIM operation on any mounted file
system using the fstrim command with the -v
(verbose) flag:
sudo fstrim -v /mnt/instance-storeThe output reports the total number of bytes discarded:
/mnt/instance-store: 412.6 GiB (443023933440 bytes) trimmed
To trim all mounted file systems listed in /etc/fstab
that support the discard operation, use the -a flag:
sudo fstrim -avAutomating Periodic TRIM with systemd
Modern Linux distributions (including Amazon Linux 2, Amazon Linux
2023, Ubuntu, and RHEL/CentOS) include a built-in systemd
timer named fstrim.timer that automatically executes
fstrim.service once a week on all supported file systems
mounted from /etc/fstab.
To check the status of the timer and enable it:
sudo systemctl enable --now fstrim.timer
sudo systemctl status fstrim.timerIf your instance store experiences heavy write and delete churn
throughout the day, a weekly schedule may not be frequent enough to
prevent write amplification. You can override the
fstrim.timer schedule to run daily or hourly by creating a
drop-in configuration file:
sudo mkdir -p /etc/systemd/system/fstrim.timer.d
cat << 'EOF' | sudo tee /etc/systemd/system/fstrim.timer.d/override.conf
[Timer]
OnCalendar=
OnCalendar=daily
EOF
sudo systemctl daemon-reload
sudo systemctl restart fstrim.timerNote that fstrim -a only processes file systems that are
present in /etc/fstab. If you mount your ephemeral EC2
instance store volumes dynamically via a boot script without adding
entries to /etc/fstab, you should either add them to
/etc/fstab (using the nofail option so
instance stop/start cycles or missing ephemeral drives do not halt boot)
or create a dedicated cron job targeting the specific mount point:
# Example /etc/cron.daily/trim-instance-store
#!/bin/sh
/sbin/fstrim -v /mnt/instance-store >> /var/log/fstrim.log 2>&1Method 2: Continuous TRIM via Mount Options
Instead of waiting for a scheduled batch job, you can configure the
Linux file system to issue TRIM commands immediately whenever files are
deleted by mounting the file system with the discard
option.
Mounting Manually with Discard
To mount an ext4 or XFS volume with
continuous TRIM enabled:
sudo mount -o defaults,noatime,discard /dev/nvme1n1 /mnt/instance-storeConfiguring Persistent Mounts in /etc/fstab
To ensure the setting persists across reboots, add the
discard and nofail options to
/etc/fstab:
UUID=<your-filesystem-uuid> /mnt/instance-store xfs defaults,noatime,discard,nofail 0 2
Trade-offs Between Periodic and Continuous TRIM
While continuous discard keeps free space reclaimed in
real time, issuing synchronous TRIM commands during every file deletion
can introduce latency spikes for workloads that delete many small files
concurrently. On older SATA SSDs, queued TRIM was not always supported,
forcing the drive to pause normal read/write queues to process the
discard command. Although modern NVMe EC2 instance store volumes handle
asynchronous Dataset Management Deallocate commands
efficiently, Linux kernel documentation and AWS best practices still
generally recommend periodic fstrim unless your workload
deletes massive volumes of data continuously and saturates the drive
faster than a periodic timer can run.
| Feature | Periodic TRIM (fstrim) |
Continuous TRIM
(-o discard) |
|---|---|---|
| Execution Trigger | Scheduled (cron or systemd
timer) |
Immediate upon file deletion |
| Foreground I/O Impact | Minimal; batches deallocations during off-peak times | Can add overhead during heavy small-file deletions |
| Best Use Case | General databases, caching, logs, and high-IOPS workloads | Workloads with rapid, massive file turnover that fill the disk between cron intervals |
Configuring TRIM with LVM and Software RAID (mdadm)
Because individual EC2 instance store volumes cannot be resized or
combined at the AWS infrastructure level, administrators frequently
stripe multiple instance store SSDs using Linux software RAID
(mdadm) or Logical Volume Manager (LVM). For TRIM commands
to reach the physical SSDs, every layer in the storage stack must pass
discard requests down to the underlying devices.
Software RAID (mdadm)
Modern Linux kernels automatically pass discard requests through
RAID 0, RAID 1, RAID 10, and
RAID 5/6 arrays created with mdadm, provided
the underlying NVMe or SSD block devices report discard support. You can
verify that the assembled md device supports discard by
running lsblk --discard and confirming that
/dev/md0 displays non-zero DISC-GRAN and
DISC-MAX values.
Logical Volume Manager (LVM)
LVM passes fstrim and file system discard
operations down to physical volumes automatically. However, if you
remove or reduce a Logical Volume (lvremove or
lvreduce) and want LVM itself to issue a discard command to
the freed physical extents immediately, you must enable
issue_discards in /etc/lvm/lvm.conf:
devices {
...
issue_discards = 1
}After updating /etc/lvm/lvm.conf, rebuild your initial
ramdisk (for example, sudo dracut -f or
sudo update-initramfs -u) if LVM volumes are initialized
early in the boot process.
Combining TRIM with SSD Over-Provisioning
Even with regular TRIM operations, if a file system on an SSD instance store volume is filled close to 100% capacity, the SSD controller has very few free blocks available to absorb incoming writes and perform wear leveling without immediate garbage collection penalties.
For write-intensive applications on EC2 instance store volumes, you
can complement TRIM with host-level over-provisioning. By partitioning
only 80% to 90% of the raw block device (after running
blkdiscard on the entire drive) and leaving the remaining
10% to 20% unallocated and unpartitioned, you guarantee a permanent pool
of trimmed, free flash blocks that the SSD controller can use to sustain
peak write throughput and low latency under heavy load.