Proxmox Storage Guide: local-lvm, ZFS, NFS, and When to Use Each

A practical breakdown of Proxmox storage backends — what local-lvm actually is, when ZFS makes sense, how to add NAS storage over NFS, and the storage layout decisions that affect your cluster's performance and reliability.

Storage configuration is the most confusing part of a new Proxmox install. The installer creates local and local-lvm by default, and most guides say “use local-lvm for VMs and containers” without explaining why — or what you’d use instead. This post covers the options in plain terms and the setup steps for adding shared NFS storage to a cluster.


What the default storage pools actually are

When Proxmox installs, it creates:

Pool name Type What it stores Location
local Directory ISO images, LXC templates, backups /var/lib/vz/
local-lvm LVM thin pool VM disks, CT root filesystems LVM thin pool on the NVMe

local-lvm is not a directory — it’s an LVM thin provisioning pool. Each VM or CT disk is allocated as a logical volume (LV) inside the pool. The major consequence: you can’t browse it with ls. You access volumes with lvs or lsblk.

pvelab04 — inspect the LVM pool

# List logical volumes
lvs

# List volume groups
vgs

# Show the thin pool
lvs data/vm-data

The output shows your VMs and CTs as individual LVs like vm-100-disk-0, vm-101-disk-0, etc.


Storage backend comparison

BackendProsCons
local-lvmFast · thin provisioning · snapshotsNo filesystem access · local only
ZFSChecksums · compression · native snapshotsHigh RAM usage (1 GB per TB minimum)
NFSShared across nodes · easy setupNetwork latency · single NAS SPOF
CephHA · distributed · scalableComplex · needs 3+ OSD nodes

For a homelab with 1–4 nodes: local-lvm for VM/CT disks, local for ISOs and templates, and NFS from a NAS (if you have one) for shared backups and bulk storage. ZFS makes sense if you have the RAM to spare (8+ GB per node) and want checksumming/compression. Ceph is overkill unless you’re building a 5+ node cluster specifically for high availability.


Task 1: Check current storage usage

1View storage usage across the cluster2 min

In the Proxmox web UI: Datacenter → Storage. This shows each storage pool, its type, available space, and which nodes it’s active on.

From the command line:

pvelab04 — check storage usage

# Overall storage summary
pvesm status

# Disk usage for local volumes
df -h /var/lib/vz

# LVM thin pool usage
lvs --units g data/vm-data

Task 2: Add NFS storage from a NAS

NFS storage is valuable for a cluster because it’s accessible from all nodes — a backup job started on pvelab01 can be read and restored from pvelab03. Most NAS devices (Synology, TrueNAS, QNAP) support NFS out of the box.

1Configure NFS exports on your NAS10 min

On a Synology NAS: Control Panel → Shared Folder → Edit → NFS Permissions → Create.

Set:

  • Hostname or IP: 10.0.0.0/24 (allow entire lab subnet)
  • Privilege: Read/Write
  • Squash: No mapping
  • Security: sys

Note the NFS path shown (e.g. /volume1/proxmox-backups).

For TrueNAS: Shares → UNIX Shares (NFS) → Add. Set the path and allowed hosts similarly.

2Add the NFS storage in Proxmox5 min

In the Proxmox web UI: Datacenter → Storage → Add → NFS.

Field Value
ID nas-backups
Server 192.168.1.100 (your NAS IP)
Export /volume1/proxmox-backups
Content Backups, ISO Images, CT Templates
Nodes All

Click Add. The storage appears immediately if the NFS share is accessible.

Verify NFS mount from any PVE node

# Should show the NAS storage
pvesm status

# Check the actual mount
mount | grep nas-backups

# Write test
touch /mnt/pve/nas-backups/test-write && rm /mnt/pve/nas-backups/test-write
echo "Write test: OK"
3Configure backup jobs to use NAS storage3 min

In Datacenter → Backup → Add: set Storage to nas-backups. Now backups go to the NAS instead of local disk — accessible from any node for restores, and persistent even if the Proxmox node’s NVMe fails.


Task 3: Expand local-lvm storage

If your NVMe is getting full, there are two options: add a second disk, or reclaim space.

1Check what's consuming space in local-lvm3 min
pvelab04 — audit LVM usage

# List all volumes and their sizes
lvs -o lv_name,lv_size,pool_lv data

# Find the largest volumes
lvs -o lv_name,lv_size data | sort -k2 -rh | head -10
2Remove unused volumes5 min

Stopped/deleted containers often leave orphaned volumes. Identify them by comparing the LV list with your active CT/VM IDs:

pvelab04 — identify orphaned volumes

# Active CTs
pct list

# Active VMs
qm list

# All LVs in the pool
lvs data | grep -v "^  LV"

# Manually remove an orphaned volume (replace 999 with the VMID)
lvremove data/vm-999-disk-0
Danger

Only remove volumes for VMIDs that no longer exist. Check both pct list and qm list — a VMID might be a VM even if you think it’s a CT. There is no undo for lvremove.

3Add a second NVMe disk to the pool10 min

If you’ve added a second NVMe (the HP EliteDesk G4 has an M.2 slot), you can extend the LVM pool to include it:

pvelab04 — extend LVM pool with second disk

# Identify the new disk (will show as unpartitioned)
lsblk

# Initialize as a physical volume (replace nvme1n1 with your disk)
pvcreate /dev/nvme1n1

# Add to the existing volume group
vgextend data /dev/nvme1n1

# The thin pool automatically uses the new space
pvesm status

NVMe drives that consistently perform in the HP EliteDesk G4:


Task 4: Set up ZFS on a node with sufficient RAM

ZFS is worth it on nodes with 16+ GB RAM. The main advantages for homelab use: transparent compression (typically 1.5–2× on container root filesystems), checksumming (detects bit rot), and native snapshots that PBS can use. Note: the common “1 GB RAM per TB of storage” rule for ZFS ARC is widely considered a myth — ARC sizes to your working set, not your pool capacity. On a 16 GB homelab node the ARC will use whatever RAM your workloads don’t, which is the correct behavior.

1Create a ZFS pool from a second disk5 min
pvelab01 — create ZFS pool

# List available disks
lsblk

# Create a single-disk pool (no redundancy — accept the risk for homelab)
# Replace sdb with your disk identifier
zpool create -f tank /dev/sdb

# Enable compression (LZ4 is fast with minimal CPU overhead)
zfs set compression=lz4 tank

# Verify
zpool status tank
zfs get compression tank
2Add ZFS pool as Proxmox storage3 min

In Datacenter → Storage → Add → ZFS:

Field Value
ID zfs-tank
ZFS Pool tank
Content Disk image, Container
Nodes pvelab01 (the node with the pool)

ZFS storage is node-local — other nodes can’t access it directly. If you want shared ZFS, that requires either Ceph or exporting via NFS.


Storage Type Content Available on
local-lvm LVM thin CT disks, VM disks Each node (local)
local Directory ISOs, templates Each node (local)
nas-backups NFS Backups All nodes
zfs-tank (optional) ZFS CT disks (compressed) Single node

This gives you fast local storage for workloads, shared NAS for backup durability, and keeps complexity manageable.

Recommended hardware for expanded storage:


Related posts:

This post contains Amazon affiliate links (tag: buildahomelab-20). I earn a small commission on qualifying purchases at no extra cost to you.