Every virtual disk you attach to a VM in Proxmox VE has a Cache dropdown sitting quietly in the Hardware tab, usually left on its default value. Most guides on creating VMs skip right past it, and most of the time that's fine — but this single setting controls how aggressively QEMU is allowed to lie to your guest OS about when data has actually reached physical storage. Get it wrong on the wrong backend, and you trade a measurable performance gain for a real chance of corrupting a database after a host crash. Get it right, and you can safely claw back significant IOPS without touching anything else in your storage stack.
This guide explains what each Proxmox VE cache mode actually does at the QEMU level, why the "safe" choice changes depending on whether your storage is ZFS, Ceph, LVM, or NFS, and how the cache mode interacts with the aio and iothread settings sitting right next to it. It also covers how to benchmark the difference on your own hardware instead of trusting a forum post written against different disks.
What "Cache Mode" Actually Controls
When a VM writes to its virtual disk, that write doesn't go straight from the guest's block layer to the physical platter or NAND. It passes through several layers first: the guest's own page cache, QEMU's block layer, potentially the Proxmox host's page cache, and finally whatever caching the underlying storage device or controller does. The Cache setting in Proxmox VE controls one specific link in that chain: whether QEMU uses the host's page cache when servicing the guest's I/O, and whether it tells the guest a write is "done" before or after that write is durable.
Two behaviors change based on the mode you pick:
- Whether the host page cache is used at all — using it can absorb repeated reads and coalesce writes, at the cost of holding dirty data in host RAM that hasn't hit disk yet.
- Whether QEMU honors the guest's flush/fsync requests — a well-behaved guest filesystem periodically asks the virtual disk to guarantee that everything written so far is durable (this is how databases implement crash consistency). Some cache modes honor that request faithfully; one deliberately ignores it.
Proxmox VE exposes five values in the Cache dropdown: No cache (the default, internally cache=none), Write through (cache=writethrough), Write back (cache=writeback), Write back (unsafe) (cache=unsafe), and Direct sync (cache=directsync).
No Cache (the Default)
cache=none opens the backing file or block device with O_DIRECT, which bypasses the host's page cache entirely. Every guest write goes straight to the storage layer underneath, and every guest read comes straight from it. QEMU still reports write completion to the guest as soon as the write reaches the host's I/O queue, which is one layer earlier than "physically on disk" for most storage — but critically, it does not hold unflushed data in host RAM the way writeback does, and it honors guest flush requests by actually flushing the underlying device.
This is why the Proxmox documentation describes it as the balance point: you're not paying the cost of double-caching (host page cache duplicating work the guest's own page cache already does), but you're also not silently buffering writes in host memory where a host crash could lose them. For the vast majority of VMs — general-purpose Linux and Windows guests, web servers, application servers, small internal tools — this is the right answer and you shouldn't need to touch it.
Write Through
cache=writethrough does use the host page cache for reads, but every write triggers an immediate fsync before QEMU reports completion to the guest. That makes it the most conservative option with data loss on the table: a write is never acknowledged until it is genuinely durable on the host's storage. The cost is exactly what you'd expect — every single write pays a synchronous flush penalty, which on spinning disks or high-latency network storage can be brutal for anything write-heavy.
In practice this mode is rarely the right choice on modern SSD or NVMe-backed storage, where none gives you nearly the same safety guarantees at meaningfully better throughput. Write through mostly shows up in older guides written when host page cache reliability was more of a live question, or in environments where the storage backend itself doesn't handle O_DIRECT well and writethrough is used as a workaround.
Write Back
cache=writeback is where the performance/safety tradeoff becomes explicit. QEMU uses the host page cache for both reads and writes, and reports a write as complete to the guest as soon as it lands in that host cache — before it's actually been flushed to the underlying device. This is fast, because the host can coalesce many small writes into fewer, larger, sequential ones, and because bursty write patterns get absorbed by RAM instead of stalling on physical I/O.
The safety story depends entirely on what kind of failure you're worried about:
- Guest crash or reboot: Safe. The host page cache is untouched by a guest-level failure, and Proxmox/QEMU will flush it normally.
- Host crash, host kernel panic, or power loss on the Proxmox node: Not safe. Any writes sitting in the host page cache that haven't been flushed yet are gone, and the guest filesystem believes those writes succeeded because QEMU already told it so.
Writeback does still honor the guest's explicit flush requests — when the guest filesystem or a database issues an fsync/barrier, QEMU flushes the host cache for real at that point. So a well-behaved journaling filesystem or a database with proper write-ahead logging is still crash-consistent up to its last acknowledged flush; you only lose the writes that happened after the last flush and before the host died. Whether that's an acceptable risk depends entirely on your power infrastructure (UPS, redundant PSUs) and how tolerant the workload is of losing a few seconds of unflushed writes.
Write Back (Unsafe)
cache=unsafe is writeback with one more guarantee removed: QEMU stops honoring flush requests from the guest altogether. When the guest asks for an fsync, QEMU acknowledges it immediately without actually flushing anything. This is explicitly not intended for production data — Proxmox and upstream QEMU both document it as a mode for disposable or reproducible workloads where losing the entire disk state on host failure is an acceptable outcome.
Realistic use cases: template-building pipelines where you install packages into a VM and then convert it to a template (if the host dies mid-build, you just rerun the pipeline), throwaway CI/test VMs, one-time OS installs where you'll snapshot immediately afterward, or benchmarking runs where you specifically want to measure storage throughput without any flush overhead. Never use this on a VM holding data you'd be upset to lose, and never leave it set on a VM after the disposable phase of its life is over — it's easy to forget it's enabled.
Direct Sync
cache=directsync combines O_DIRECT (bypassing host page cache, like none) with O_DSYNC (forcing every write to be synchronous, like writethrough). It is the slowest of the five modes because it gets no benefit from host caching and pays a synchronous flush on every single write, but it is also the most conservative: there is no host-side buffering window at all in which data could be lost.
This is the mode Proxmox VE recommends specifically for ZFS-backed storage, and the reason is caching architecture, not extra paranoia.
Why ZFS Changes the Recommendation
ZFS maintains its own read cache — the ARC (Adaptive Replacement Cache) — and its own write semantics via the ZFS Intent Log (ZIL) and transaction groups. If you layer the host's page cache on top of ZFS's own caching by using none or writeback on a zvol-backed disk, you end up double-caching: the same data gets cached once by ZFS's ARC and again by the host page cache that QEMU's cache mode enables, wasting RAM and adding a layer of indirection that doesn't improve durability.
Worse, on writeback, unflushed writes now sit in the host page cache above ZFS, meaning a host crash can lose data ZFS itself would otherwise have handled safely through its own transactional model. Using directsync (or plain none, which many ZFS-experienced operators also consider acceptable since ZFS's own semantics provide the durability guarantee once a write actually reaches the pool) avoids the host-level double buffering and lets ZFS's own caching and copy-on-write transaction groups do the job they're designed for.
The same logic extends, with different specifics, to other storage backends:
| Storage backend | Typical recommendation | Why |
|---|---|---|
| ZFS (zvol or dataset) | Direct sync, or No cache | Avoids double-caching against ZFS's own ARC/ZIL |
| Ceph RBD | No cache | RBD has its own client-side caching (librbd cache); host page cache adds no benefit and RBD is not a local block device host caching helps with |
| LVM / LVM-thin (raw block) | No cache | Direct block device access; O_DIRECT is well supported and gives predictable performance |
| Directory storage (qcow2/raw on a filesystem) | No cache, or Write back for throughput-bound, loss-tolerant workloads | qcow2 metadata operations can benefit from writeback on slower filesystems, at the safety cost described above |
| NFS-backed storage | No cache (test carefully — some NFS servers behave poorly with O_DIRECT) | Depends heavily on the NFS server's own caching and export options |
These are starting points, not absolutes — validate against your own storage before committing a fleet of production VMs to a non-default setting.
The Async I/O (aio) Setting
Sitting next to Cache in the disk options is Async IO, which controls how QEMU actually issues I/O requests to the host kernel, independent of caching behavior. Proxmox VE exposes three values:
- io_uring — the modern Linux asynchronous I/O interface, and the current Proxmox VE default for new disks on recent kernels. It offers lower overhead and better queue depth handling than the older interfaces, especially under high concurrency.
- native — Linux AIO (the older kernel async I/O interface). Requires
O_DIRECTto function correctly, so it's only meaningful paired with cache modes that use direct I/O (noneordirectsync); pairing native with writeback/writethrough silently falls back to less efficient behavior in QEMU. - threads — a thread-pool-based fallback that works with any cache mode, including those that go through the host page cache. It's less efficient than io_uring or native but is the safe fallback on storage backends or kernels where the async interfaces misbehave (this is common with some network filesystem clients).
If you're troubleshooting unexpectedly poor I/O performance after changing cache mode, check the aio setting too — a cache mode change without a matching aio value can leave you on a suboptimal combination.
IO Thread
The IO Thread checkbox is a separate but related performance option: enabling it makes QEMU dedicate a single I/O thread per virtual disk controller rather than processing storage I/O in the main QEMU event loop or vCPU threads. This matters most on VMs with multiple vCPUs doing concurrent disk I/O, where a shared event loop can become a bottleneck. It requires the disk to be attached via VirtIO SCSI single (not the shared "VirtIO SCSI" controller mode) or VirtIO Block. If you're tuning for I/O performance, pair a properly chosen cache mode with IO Thread enabled and a VirtIO SCSI single controller — the three settings compound.
Benchmarking Before You Commit
Don't take any of the above as gospel for your specific hardware — verify it. Boot a disposable test VM on the same storage your production VMs use, and run fio from inside the guest with a workload pattern that resembles your real one:
# Random 4K writes, simulating database-style small synchronous I/O
fio --name=randwrite --ioengine=libaio --iodepth=32 --rw=randwrite \
--bs=4k --direct=1 --size=2G --numjobs=4 --runtime=60 \
--time_based --group_reporting
# Sequential large writes, simulating bulk transfer / backup-style I/O
fio --name=seqwrite --ioengine=libaio --iodepth=16 --rw=write \
--bs=1M --direct=1 --size=4G --numjobs=1 --runtime=60 \
--time_based --group_reporting
Run each test with the disk set to none, then again after switching to writeback (shut the VM down between changes — cache mode is not hot-swappable), and compare IOPS and latency, not just throughput. On NVMe-backed local storage the gap is often smaller than people expect; on network storage or spinning disks it can be dramatic. Let the numbers on your hardware make the decision, not a blog post benchmarking different disks entirely.
Recommended Defaults by Workload
- General-purpose production VMs (web apps, internal services): No cache. It's the Proxmox default for a reason and needs no special handling on host failure.
- Databases and anything with its own write-ahead log (PostgreSQL, MySQL/InnoDB, etc.): No cache, or Direct sync on ZFS. These workloads already implement their own crash-consistency guarantees and are exactly the case where silently losing acknowledged writes on host failure is most damaging.
- ZFS-backed storage generally: Direct sync (or No cache if you've specifically validated the ARC/host-cache interaction is a non-issue for your workload).
- Template builds, disposable CI runners, one-shot OS installs before first snapshot: Write back (unsafe) is acceptable, given you understand the entire disk is at risk on host failure and you'd simply rebuild it.
- Read-heavy VMs on slow network storage where a small write-loss window is tolerable: Write back can be a reasonable, deliberate tradeoff — document that decision so a future admin doesn't assume it's the default.
Changing the Cache Mode
In the web UI: shut the VM down, open Hardware → [disk] → Edit, change the Cache dropdown, and confirm. The change takes effect the next time the VM starts — it is not a hot-pluggable setting.
From the CLI, use qm set against the specific disk, preserving its existing volume and other options:
# View the current disk configuration first
qm config 100
# Example: change scsi0 on VM 100 to no cache with io_uring
qm set 100 --scsi0 local-zfs:vm-100-disk-0,cache=none,aio=io_uring
# Example: ZFS-backed disk, recommended direct sync
qm set 100 --scsi0 local-zfs:vm-100-disk-0,cache=directsync
Always copy the full existing disk line from qm config before running qm set on it — omitting an existing option like size= or discard=on from the command will clear it, since qm set replaces the entire disk definition string for that bus/slot.
Troubleshooting Common Symptoms
"Writes got dramatically slower after I set writethrough or directsync" — this is expected behavior, not a bug. Both modes force a synchronous flush on every write. If this is unacceptable, you likely want none instead, provided your durability requirements allow it.
"A VM's disk appears corrupted after a host power loss, and cache was set to writeback" — this is the exact failure mode writeback warns about. There is no way to recover unflushed writes that were only ever in host RAM; the fix going forward is switching to none or directsync and, if this VM matters, adding a UPS with clean shutdown automation so host power loss stops being a live threat at all.
"Backups or snapshots seem to interact oddly with my cache setting" — Proxmox VE's own backup mechanism (vzdump, and PBS-based backups) issues explicit flushes as part of the backup process regardless of the VM's configured cache mode, so a snapshot or backup taken mid-run is still consistent from the guest filesystem's perspective. The risk cache mode introduces is specifically around unplanned host failure, not planned backup operations.
Frequently Asked Questions
Can I change cache mode without recreating the disk? Yes — it's a QEMU-level setting on the existing disk, not a property of the disk image itself. Shut the VM down, change it, start it back up.
Does cache mode affect LXC containers? No. LXC containers share the host kernel and access storage directly through the host filesystem; the Cache dropdown only applies to QEMU-based VM disks.
Is "No cache" actually safe for production databases? Yes, for the failure modes that matter to a properly configured database. It doesn't buffer unflushed writes in host RAM the way writeback does, and it honors flush requests, so a database's own write-ahead log stays crash-consistent through a host failure.
Why does Proxmox default new disks to "No cache" instead of "Write back" if writeback is faster? Because the default needs to be safe for every workload someone might put on it without reading this article first. Write back is an opt-in performance trade, not a universal upgrade.
Does the cache mode matter for read performance, or only writes? Both No cache and Direct sync bypass host caching for reads too, meaning repeated reads of the same block go back to storage each time rather than being served from host RAM. Write back and Write through do cache reads in host RAM, which can meaningfully help read-heavy workloads on slower backends — one more reason to benchmark your actual access pattern rather than assuming write safety is the only variable in play.
Should I use the same cache mode for every disk on a VM? Not necessarily. A VM's OS disk and a separate data disk can have different cache settings — for example, a database VM might run none on its OS disk and directsync on a ZFS-backed data volume holding the actual database files.
Conclusion
Proxmox VE's disk cache modes are one of those settings that look like a minor dropdown but encode a real decision about what you're willing to lose if the host itself fails. None is the right default for almost everything and rarely needs revisiting. Directsync earns its place specifically on ZFS, where it avoids fighting ZFS's own caching model. Writeback and its unsafe variant are legitimate tools when you've deliberately decided a class of VMs — disposable builds, throwaway test environments — doesn't need to survive a host crash intact. The mistake to avoid isn't picking the "wrong" mode in isolation; it's picking a fast mode for a workload's convenience without having consciously accepted what a host power loss would do to it.