Linux VPS

KVM disk performance: cache modes, io modes and iothreads

Tune KVM virtual disk performance: compare cache=none, writeback and writethrough, io=native, threads and io_uring, add iothreads, enable discard, and measure results with fio.

AdvancedKVM hosts2 min read

VM disk settings can make a large difference to I/O latency and data safety. This guide explains KVM disk performance options in libvirt: cache modes, I/O modes and iothreads, with safe defaults for production.

Before you start

Cache modes

ModeHost page cacheSafetyUse
noneBypassed (O_DIRECT)Safe; guest flushes honouredRecommended default; required for live migration on shared storage
writebackUsed for reads and writesSafe if the guest issues flushes; data in host cache until flushedCan be faster on slow storage
writethroughReads cached, writes synchronousSafeSlow writes
directsyncBypassed, every write synchronousVery safeSlowest
unsafeIgnores flushesData loss on host crashThrowaway test VMs only

I/O modes

  • io='native': Linux AIO, efficient with cache='none' on raw devices or preallocated files.
  • io='threads': a thread pool; works with any cache mode.
  • io='io_uring': newer interface on recent kernels and QEMU, often the best choice when available.

Example disk definition

<disk type='block' device='disk'>
  <driver name='qemu' type='raw' cache='none' io='native' discard='unmap' iothread='1'/>
  <source dev='/dev/vg_vms/web01-disk0'/>
  <target dev='vda' bus='virtio'/>
</disk>

Add iothreads at the domain level:

<iothreads>2</iothreads>

An iothread moves disk processing off the main QEMU thread, which helps busy disks and multi-disk VMs. For virtio-scsi, set the iothread on the controller instead.

Discard and TRIM

discard='unmap' lets the guest free unused blocks on thin storage (qcow2, LVM-thin, ZFS, Ceph). Inside the guest, enable the weekly trim timer: sudo systemctl enable --now fstrim.timer.

Other factors

  • Storage backend matters most: NVMe beats SATA SSD beats HDD; see NVMe vs SSD vs HDD.
  • Raw on LVM/ZFS avoids qcow2 metadata overhead; see qcow2 vs raw.
  • Use virtio-blk for lowest latency or virtio-scsi for many disks.

Measure

fio --name=randrw --filename=/root/fio.test --size=2G --rw=randrw --bs=4k --iodepth=32 --ioengine=libaio --direct=1 --runtime=60 --time_based

Run the same test inside the VM before and after a change, at a quiet time.

Frequently asked questions

Is writeback dangerous?

Not with modern guests that send flushes; data is safe after a flush. unsafe is the dangerous one.

Can I change cache mode live?

No, edit the XML and fully restart the VM.

Do VPS customers control this?

No, it is a host setting. Customers can enable fstrim and use efficient filesystems.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.