ZFS is the storage layer a lot of Proxmox users settle on, and for good reason: it gives you software RAID, snapshots, compression, and checksum-based data integrity in one system, without a hardware RAID card. For VM storage that means thin-provisioned disks, instant snapshots, and the ability to catch and repair silent corruption — features you’d otherwise stitch together from several tools.
The price is RAM and a bit of upfront planning. ZFS caches aggressively, and the RAID level you choose at pool creation is hard to change later, so it pays to get the layout right the first time. This guide walks through creating a pool, adding it as Proxmox storage, and the handful of settings worth tuning — ARC size, compression, and regular scrubs — on Proxmox VE 8.x.
If you’re still deciding between storage types, the LVM vs LVM-Thin vs ZFS comparison lays out where each one fits. This guide assumes you’ve decided on ZFS.
The one rule before you start: no hardware RAID
This trips up people coming from traditional servers, so it goes first. ZFS wants direct access to the raw disks. It manages redundancy itself, checks every block against a checksum, and repairs damage from its redundant copies. A hardware RAID controller hides the individual disks behind its own array and silently breaks all of that.
Choosing a RAID level
ZFS RAID (called the vdev layout) is decided when you create the pool, and changing it afterward usually means destroying and rebuilding. So choose deliberately based on your disk count and whether you care more about performance or usable capacity.
Common ZFS pool layouts
| Single disk | No redundancy. Fine for scratch or test pools, never for data you care about. One disk failure loses everything. |
|---|---|
| Mirror (RAID1) | Two (or more) disks holding the same data. Fast, simple, easy to grow by adding mirror pairs. Best for VM workloads with lots of small random I/O. Loses half the raw capacity. |
| RAIDZ1 | 3+ disks, tolerates one disk failure. Better capacity efficiency than mirrors, but slower for random writes and a long, risky resilver on large disks. |
| RAIDZ2 | 4+ disks, tolerates two disk failures. The safer choice for larger pools where a resilver takes a long time and a second failure is a real risk. |
For a busy VM host, mirrors usually win — they handle small random I/O better and resilver faster. For bulk capacity where throughput matters more than IOPS (backups, media, archives), RAIDZ2 gives you more usable space with solid redundancy. Avoid RAIDZ1 on large modern disks, because the resilver after a failure takes long enough that a second disk can die mid-rebuild.
Step 1: Create the ZFS pool
You can create the pool two ways. The simplest is during the Proxmox installer, which offers ZFS RAID options for the boot disks directly. For data pools added after install, do it from the shell or the GUI.
In the web interface: Node → Disks → ZFS → Create: ZFS. Pick the disks, choose the RAID level, name the pool, and Proxmox creates it with sensible defaults (including LZ4 compression).
From the command line, zpool create does the same with full control. First find your disk identifiers:
# list disks by stable /dev/disk/by-id names (use these, not /dev/sdX)
ls -l /dev/disk/by-id/
Then create the pool. A two-disk mirror named tank:
# mirror of two disks
zpool create -o ashift=12 tank mirror \
/dev/disk/by-id/ata-DISK1 \
/dev/disk/by-id/ata-DISK2
Or a four-disk RAIDZ2:
# RAIDZ2 across four disks, tolerates two failures
zpool create -o ashift=12 tank raidz2 \
/dev/disk/by-id/ata-DISK1 \
/dev/disk/by-id/ata-DISK2 \
/dev/disk/by-id/ata-DISK3 \
/dev/disk/by-id/ata-DISK4
Step 2: Add the pool as Proxmox storage
A pool created in the GUI is registered as storage automatically. If you made it from the shell, add it under Datacenter → Storage → Add → ZFS, pick the pool, and choose the content types.
From the command line:
# register the ZFS pool 'tank' as Proxmox storage for VM disks and containers
pvesm add zfspool tank-zfs --pool tank --content images,rootdir
ZFS storage in Proxmox holds Disk image (VM disks) and Container root filesystems. These are stored as ZFS datasets/zvols, not files, which is what gives you native snapshots and thin provisioning per disk.
Step 3: Cap the ARC so VMs keep their RAM
ZFS uses spare RAM as a read cache called the ARC, and it’ll grow to use a large share of memory by default. That’s great for a dedicated storage box, but on a Proxmox host you want most of the RAM for VMs. Cap the ARC so it doesn’t compete with your guests.
Set a maximum in bytes through the kernel module. For example, to cap the ARC at 8 GB:
# set the ARC max (8 GiB here) — value is in bytes
echo "options zfs zfs_arc_max=8589934592" > /etc/modprobe.d/zfs.conf
# rebuild the initramfs so the setting applies at boot
update-initramfs -u
# reboot for it to take effect
reboot
ZFS does give memory back under pressure, but an explicit cap removes the surprise of “where did my RAM go?” and keeps memory accounting predictable when you’re sizing VMs.
Step 4: Compression and snapshots
Two of ZFS’s best features need almost no work.
Compression is on by default (LZ4) for pools Proxmox creates, and you should leave it on. LZ4 is fast enough to be effectively free, saves space on typical VM data, and can improve throughput because there’s less to read and write. Confirm it’s set:
# check compression on the pool
zfs get compression tank
Snapshots are instant and space-efficient. Proxmox uses them automatically when you snapshot a VM whose disk is on ZFS, and you can also take them directly:
# snapshot a dataset manually
zfs snapshot tank/vm-101-disk-0@before-update
# list snapshots
zfs list -t snapshot
Because ZFS snapshots are copy-on-write, they take no space at creation and only grow as data diverges. That makes them ideal for a quick safety net before a risky change inside a VM.
Step 5: Scrub regularly to catch corruption
A scrub reads every block in the pool, verifies it against its checksum, and repairs any damage using the redundant copies. This is how ZFS catches silent corruption (bit rot) before it spreads into your backups.
Proxmox sets up a systemd timer to scrub on a schedule, but it’s worth knowing the manual commands:
# start a scrub
zpool scrub tank
# watch progress and overall pool health
zpool status tank
zpool status is the command to know. It shows pool health, any errors found, resilver/scrub progress, and which disk has a problem if one does. Check it after a scrub and any time something feels off.
Wrapping up
ZFS gives a Proxmox host serious storage capability without extra hardware: software RAID, instant snapshots, transparent compression, and checksums that catch corruption hardware RAID would miss. The decisions that matter are made early — pass disks through directly (no hardware RAID), pick the right vdev layout for your workload, and cap the ARC so VMs get their memory. After that, ZFS mostly runs itself, as long as scrubs are happening and you act on a degraded pool.
For the wider storage picture and when ZFS beats the alternatives, read Proxmox LVM vs LVM-Thin vs ZFS. To move an existing VM disk onto your new pool, see moving a Proxmox VM disk to another storage, and to protect what’s on it, set up Proxmox backup and restore. For more walkthroughs, browse the Proxmox guides.