Virtual Disks
A VM's disk is typically a file on the hypervisor's filesystem — formats like QCOW2 (QEMU Copy-On-Write version 2) for KVM, VMDK for VMware, or VHD/VHDX for Hyper-V. These files can be:
- Thick Provisioned (Eager Zeroed): The full disk size is allocated immediately on the host. A 100 GB virtual disk consumes 100 GB of host storage from the moment it's created. Predictable, no surprises.
- Thin Provisioned: The file starts small and grows as the VM writes data. A 100 GB virtual disk might only consume 8 GB of host storage if the VM has only written 8 GB. Efficient — until it isn't.
The Thin Provisioning Trap
Thin provisioning enables storage overcommit, just like memory overcommit. A hypervisor host with 1 TB of storage can provision ten VMs each with a 200 GB thin-provisioned disk (2 TB total promised), betting they won't all fill up simultaneously.
The failure mode is called storage overcommit exhaustion: if VMs collectively write more data than the host has physical storage, writes start failing. From inside the VM, this looks like a disk full error — even though df -h inside the VM shows plenty of space. The VM thinks it has 200 GB; the host has run out of physical space to back the thin-provisioned file.
QCOW2 Copy-on-Write adds another layer: QCOW2 supports snapshots by writing new data to a new location and keeping the old data intact. This is how VM snapshots work — the snapshot is a QCOW2 file that records only the changes since the snapshot was taken. The base image is shared. This is efficient for storage but means that a chain of snapshots must all be read to reconstruct the current disk state, which can degrade I/O performance significantly as the chain grows.
Key Point: In production cloud environments, storage is almost always thin-provisioned. AWS EBS volumes, for example, are thin-provisioned from a large shared pool. The practical implication: always monitor actual storage consumption at the host/pool level, not just inside the VM. In Kubernetes environments, this manifests as PersistentVolumeClaims that appear to have space but cause write failures when the underlying storage pool is exhausted — a notoriously confusing failure mode.