Inside Proxmox’s LVM Snapshot Chains

For years, virtualization admins have mentally separated storage into a few neat buckets:

Storage TypeSnapshot Method
qcow2 on filesystemqcow2 backing chains/internal snapshots
ZFSNative CoW snapshots
VMware VMFSDelta VMDK chains

Then Proxmox decided to make things weird.

Recently I started digging into Proxmox’s experimental snapshot-as-volume-chain functionality for LVM storage and quickly realized this is not behaving the way most people would expect. At first glance it looks like Proxmox is suddenly storing qcow2 files on LVM-thick storage. That is not actually what is happening. What Proxmox is really doing is significantly more interesting.

Traditional LVM-Thick Behavior

Normally with classic Proxmox LVM-thick storage:

  • the LV contains raw guest-written blocks
  • the guest filesystem is directly visible on the volume
  • mounting the LV elsewhere exposes the guest partition/filesystem directly

For example:

  • guest creates ext4 filesystem
  • ext4 exists directly on the LV
  • no intermediate image format exists

This can actually be observed directly. Here is the hexdump from a traditional non-snapshot-chain LVM-thick volume:

root@proxmox-01:~# hexdump -C -n 16 /dev/mapper/proxmox-nvme-tcp-ds-03-vm-109-disk-0
00000000 eb 63 90 00 00 00 00 00 00 00 00 00 00 00 00 00 |.c..............|

That is simply an x86 boot sector.

No qcow2 metadata.
No image container.
Just raw guest blocks directly written to the LV.

You can even see the distinction in the VM configs themselves.

Traditional LVM-thick VM:
scsi0: local-lvm:vm-115-disk-0,size=37G
Experimental snapshot-chain VM:
scsi0: proxmox-nvme-tcp-ds-01:vm-101-disk-1.qcow2,iothread=1,size=150G

Notice the .qcow2 suffix. That naming change is not cosmetic.

The First Clue

Once the experimental feature is enabled, newly created disks suddenly appear to become qcow2 files. Running lvs shows entries like this:

root@proxmox-01:/# lvs
vm-100-disk-0.qcow2
vm-101-disk-1.qcow2
vm-102-disk-0.qcow2
vm-103-disk-0.qcow2

While older traditional LVM-thick volumes remain:

vm-104-disk-0
vm-109-disk-0
vm-116-disk-0

These are still just standard LVM logical volumes. The only visible difference initially is the .qcow2 suffix. That alone is strange enough. But then things get weirder.

The LV is Literally a qcow2 Container

If you inspect the contents of the LV directly, you discover the block device itself now contains qcow2 metadata. The LV is no longer “raw.” It is acting as a qcow2 image container directly on the block device. For example:

root@proxmox-01:~# qemu-img info /dev/mapper/proxmox-nvme-tcp-vg-02-vm-103-disk-0.qcow2
file format: qcow2
backing file: vm-103-disk-0.qcow2
backing file format: qcow2
compat: 1.1
extended l2: true

Even more interesting the backing file is another LV. This means the snapshot chain is no longer:

  • filesystem files
  • internal qcow2 snapshots
  • or classic LVM snapshots

Instead each chain member is its own independent thick-provisioned LV.

Proof at the Block Level

Checking the hexdump again:

root@proxmox-01:~# hexdump -C -n 16 /dev/proxmox-nvme-tcp-vg-02/vm-103-disk-0.qcow2
00000000 51 46 49 fb 00 00 00 03 00 00 00 00 00 00 02 10 |QFI.............|

That QFI signature is the qcow2 magic header. The raw block device itself is being used as the qcow2 container. Even file recognizes it:

root@proxmox-01:~# file -s /dev/proxmox-nvme-tcp-vg-02/vm-103-disk-0.qcow2
QEMU QCOW Image (v3), has backing file

Which is honestly a little strange the first time you see it on a raw LV.

Snapshot Chain Layout

Conceptually the layout looks something like this:

                    ACTIVE VM
                         |
                         v
+--------------------------------------------------+
| vm-103-disk-0.qcow2                              |
| LVM LV                                           |
|--------------------------------------------------|
| qcow2 metadata                                   |
| backing file -> snap_vm-103-disk-0_test.qcow2    |
+--------------------------------------------------+
                         |
                         v
+--------------------------------------------------+
| snap_vm-103-disk-0_test.qcow2                    |
| Separate Thick-Provisioned LVM LV                |
|--------------------------------------------------|
| qcow2 metadata + previous guest block state      |
+--------------------------------------------------+

And after multiple snapshots:

ACTIVE WRITE LAYER
|
v
vm-103-disk-0.qcow2
|
v
snap_vm-103-disk-0_test1.qcow2
|
v
snap_vm-103-disk-0_test2.qcow2
|
v
base guest blocks

This behaves much more like:

  • VMware delta disks
  • qcow2 external snapshots
  • layered image chains

Than traditional Linux LVM snapshots.

This Is NOT Classic LVM Snapshots

This is important. Proxmox is not using classic CoW LVM snapshot mechanics here. Instead:

  • qcow2 metadata manages the chain relationships
  • each chain member lives inside its own LV
  • qemu directly understands the hierarchy

So architecturally this behaves far closer to:

  • VMware snapshot chains
  • qcow2 external backing files
  • Ceph layered images

Than traditional LVM snapshots.

The Capacity Trap

There is an extremely important operational implication here. Every snapshot LV is created as another thick-provisioned LVM volume. Meaning:

  • same logical size
  • same LV allocation size
  • same apparent provisioning footprint

Example:

VM SizeSnapshotsThick LV Allocation
150 GB4 snapshots~750 GB

So while the qcow2 chain conceptually resembles sparse layered snapshots, the underlying storage allocation is still thick. This means storage can disappear very quickly.

Especially on:

  • iSCSI LUNs
  • FC-backed LVM
  • enterprise arrays
  • smaller NVMe pools
  • homelab SSD storage

This is one of those features where the architecture is extremely clever, but capacity planning suddenly matters a lot more than people expect. Of course, array-based data reduction may clean this up on the backend but the space used on the lun as reported to Proxmox will not.

Why This Is Interesting

The deeper implication here is that Proxmox is blurring the line between:

  • block storage
  • image formats
  • snapshot orchestration

Historically:

  • raw LVs were “simple”
  • qcow2 files were “feature rich”

Now those worlds are merging. And once image metadata starts living directly on block devices, some very interesting future possibilities emerge around:

  • clone acceleration
  • snapshot mobility
  • storage offload
  • XCOPY-like integrations
  • array-assisted clone operations
  • block-native snapshot chaining

Whether Proxmox goes further down that road remains to be seen. But architecturally this is one of the more interesting storage experiments happening in the open virtualization ecosystem right now.

Final Thoughts

The fascinating part isn’t simply that Proxmox added another snapshot mechanism. It’s that the distinction between “raw block storage”, “image format” and, “snapshot chain” is starting to disappear. Do I think we could use a supported clustered filesystem? Sure. Would a CSI/Cinder type integration where VM disk are volumes/luns on external storage be better? I’m coming around.

Leave a comment