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 --discard

Look 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/nvme1n1

Formatting 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/nvme1n1

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-store

The 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 -av

Automating 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.timer

If 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.timer

Note 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>&1

Method 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-store

Configuring 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.