Configuring TRIM/UNMAP for KVM/Proxmox: Reclaiming ‘Occupied’ Disk Space

Virtualization tutorial - IT technology blog
Virtualization tutorial - IT technology blog

Why Do Virtual Machine Disks Keep Bloating?

If you use KVM or Proxmox with Thin Provisioning disks (like .qcow2 or LVM-thin), the following scenario will definitely sound familiar. You delete a 20GB file inside the virtual machine, and the guest OS immediately reports the space as free. However, checking the physical host, the virtual disk file still occupies the same amount of space. It hasn’t shrunk by even a single byte.

The reason is simple: when a file is deleted, the Guest OS only marks those blocks as “free” in its file system index. The underlying virtualization layer (KVM/QEMU) is unaware of this change. It assumes those blocks still contain important data and continues to reserve space on the physical hard drive.

I once managed a Homelab cluster running 12 VMs on an Intel NUC with a 500GB NVMe drive. During a period of testing Docker, I was constantly pulling and deleting heavy images. Although the VM reported 150GB of free space, my NVMe drive was showing red because it was out of room. That’s when I realized I had forgotten to enable TRIM/UNMAP.

TRIM (for SSDs) or UNMAP (for SCSI) acts as a “common language” between the virtual machine and the physical host. It allows the Guest OS to tell the Host: “Hey, I’m done with these blocks, you can reclaim them!”. The result? Physical disk usage will automatically shrink.

Step 1: Configure Virtual Hardware

TRIM commands cannot pass through legacy controllers. You need to select the correct driver that supports this protocol.

Configuration on Proxmox VE

In the Proxmox Web UI, navigate to the VM’s Hardware section and check two items:

  • SCSI Controller: Switch to VirtIO SCSI or VirtIO SCSI single. This is currently the optimal choice.
  • Hard Disk: Ensure the Bus/Device is set to SCSI.

Most importantly: When editing the disk, you must check the Discard box. This is the switch that allows UNMAP commands to pass through the virtualization layer.

Enable Discard on Proxmox

Pure KVM/QEMU Configuration (using virsh)

If you prefer the command line, edit the VM’s XML file using the command virsh edit <vm_name>. Find the <driver> tag within the <disk> section and add the discard='unmap' attribute.

<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2' discard='unmap'/>
  <source file='/var/lib/libvirt/images/ubuntu-server.qcow2'/>
  <target dev='sda' bus='scsi'/>
</disk>

Quick note: You need to completely shut down the VM and start it again for these hardware changes to take effect.

Step 2: Enable Inside the Guest OS

After opening the path from the Host side, it’s time to teach the operating system inside the VM how to “clean house.”

For Linux Guests

You have two options: Continuous TRIM (reclaim as you go) or Periodic TRIM. I recommend Periodic TRIM to avoid sudden I/O performance drops when deleting large files.

Most modern distros like Ubuntu or Debian use fstrim.timer. Check it with the following command:

# Check if the timer is active
systemctl status fstrim.timer

# If not, enable it
sudo systemctl enable --now fstrim.timer

To see immediate results, you can force a system cleanup using the command sudo fstrim -av. If the screen shows /: 15 GiB... trimmed, congratulations, you’ve reclaimed 15GB of actual space for the Host.

For Windows Guests

Windows usually automatically detects VirtIO SCSI drives as SSDs. Check the TRIM status using Command Prompt (Admin):

fsutil behavior query DisableDeleteNotify

If the result is 0, everything is ready. If it’s 1, use the command fsutil behavior set DisableDeleteNotify 0 to enable it.

Step 3: Verifying the Results

Don’t just trust what the VM reports; look at the actual numbers on the Host. On the physical server, use the du command to check the actual size of the .qcow2 file:

# Actual space occupied on disk
du -sh /var/lib/libvirt/images/my-vm.qcow2

# Originally defined virtual capacity
ls -lh /var/lib/libvirt/images/my-vm.qcow2

If configured correctly, the number from the du command will be significantly smaller than the original virtual capacity. Additionally, the lsblk -D command inside a Linux VM will show a value in the DISC-MAX column. If it’s non-zero, it means your infrastructure properly supports TRIM.

Real-world Experience

  • SSD Emulation: In Proxmox, enable this option for Windows VMs. It helps Windows recognize the drive as an SSD and automatically optimize defragmentation, instead of treating it like a slow mechanical HDD.
  • ZFS Storage: If using ZFS, space reclamation might be delayed by a few seconds to a few minutes. This is a characteristic of the Copy-on-Write mechanism, so don’t worry.
  • Backup Benefits: This is a huge plus. Backup files will be smaller and the data compression process will be faster because it doesn’t have to process “junk” data blocks.

With just a few configuration steps, you can maximize every GB on your expensive SSDs. Good luck with your system optimization!

Share: