Install ZFS on VPS for Advanced Storage Management

Install ZFS on VPS for Advanced Storage Management

June 2026 · 8 min read

ZFS (Zettabyte File System) is an advanced filesystem developed by Sun Microsystems that provides professional-grade storage management capabilities. On a VPS, ZFS allows you to create software RAID, snapshot data, compress files, and encrypt datasets without managing separate filesystems. This guide covers installing ZFS on Ubuntu/Debian VPS and building storage pools with dataset management at the enterprise level.

What is ZFS and Why Use It on VPS

ZFS is a filesystem designed for mission-critical environments with features including:

On VPS, ZFS excels at multi-disk management, automated backups, and recovery from disk failures.

Install ZFS on Ubuntu/Debian

First, verify your Linux kernel version. ZFS supports kernel 2.6.32 and newer:

$ uname -r
5.15.0-56-generic

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="22.04.1 LTS"

Install ZFS packages:

$ sudo apt update
$ sudo apt install zfsutils-linux zfs-initramfs -y

Verify ZFS kernel modules are loaded:

$ sudo modprobe zfs
$ lsmod | grep zfs
zfs                  4063232  15

If modprobe fails, you may need to compile ZFS modules (common on some VPS hosts):

$ sudo apt install build-essential autoconf automake libtool linux-headers-$(uname -r) -y
$ sudo apt install zfs-dkms -y

Create a ZFS Pool (Zpool)

A pool is a storage container made up of one or more disks or partitions. Check available disks:

$ sudo fdisk -l
Disk /dev/sdb: 100 GiB
Disk /dev/sdc: 100 GiB

Create a RAID 1 pool (mirrored) for critical data:

$ sudo zpool create storage mirror /dev/sdb /dev/sdc

For RAID Z (similar to RAID 5 with one parity disk):

$ sudo zpool create storage raidz /dev/sdb /dev/sdc /dev/sdd

For RAID Z2 (similar to RAID 6 with two parity disks):

$ sudo zpool create storage raidz2 /dev/sdb /dev/sdc /dev/sdd /dev/sde

Check your created pool:

$ sudo zpool list
NAME      SIZE  ALLOC   FREE  CAP  HEALTH  ALTROOT
storage   200G  1.5M  200G    0%  ONLINE  -
Note: Never use disks with existing partition tables. Use whole disks or empty partitions. On VPS, use /dev/vdbX or loop devices

Manage ZFS Datasets

A dataset is a storage unit within a pool, similar to a logical volume in LVM. Set compression by default:

$ sudo zfs create -o compression=lz4 storage/backup

Set a storage quota (limit):

$ sudo zfs set quota=50G storage/backup

Create an encrypted dataset with AES-256:

$ sudo zfs create -o encryption=aes-256-gcm \
  -o keylocation=prompt -o keyformat=passphrase \
  storage/confidential

List datasets and their properties:

$ sudo zfs list
NAME               USED  AVAIL  REFER  MOUNTPOINT
storage            1.5M   200G    96K  /storage
storage/backup     100K   50G     96K  /storage/backup
storage/confidential 96K   100G    96K  /storage/confidential

Change mount point for a dataset:

$ sudo zfs set mountpoint=/mnt/backup storage/backup
$ mount | grep zfs
storage on /storage type zfs (rw,relatime,xattr,nofail)
storage/backup on /mnt/backup type zfs (rw,relatime,xattr,nofail)

Snapshots and Backup

A snapshot is a point-in-time copy of a dataset. Create one:

$ sudo zfs snapshot storage/backup@2026-06-27

List all snapshots:

$ sudo zfs list -t snapshot
NAME                             USED  AVAIL  REFER  MOUNTPOINT
storage/backup@2026-06-27        100K      -    96K  -

Clone a snapshot into a new dataset:

$ sudo zfs clone storage/backup@2026-06-27 storage/backup-clone

Send a snapshot to another pool (local backup):

$ sudo zfs send storage/backup@2026-06-27 | sudo zfs receive backup_remote/

Replicate to a remote server over SSH:

$ sudo zfs send storage/backup@2026-06-27 | ssh [email protected] \
  sudo zfs receive backup_pool/storage/backup@2026-06-27

Send only changes (incremental backup):

$ sudo zfs send -i storage/backup@2026-06-27 storage/backup@2026-06-28 | \
  ssh [email protected] sudo zfs receive backup_pool/storage/backup@2026-06-28

Automated Snapshots with zfs-auto-snapshot

Install the automatic snapshot tool:

$ sudo apt install zfs-auto-snapshot -y

Enable cron jobs (creates snapshots hourly, daily, weekly, monthly by default):

$ sudo systemctl enable zfs-auto-snapshot.service
$ sudo systemctl start zfs-auto-snapshot.service

View the cron configuration:

$ ls /etc/cron.d/ | grep zfs
zfs-auto-snapshot

$ cat /etc/cron.d/zfs-auto-snapshot
# Keep 3 hourly, 2 daily, 1 weekly snapshot
0 * * * * root /usr/sbin/zfs-auto-snapshot --keep=3 --prefix=hourly

Manually create a snapshot:

$ sudo /usr/sbin/zfs-auto-snapshot --keep=7 --prefix=manual-backup storage/

Verify ZFS is Working

Check pool status:

$ sudo zpool status storage
  pool: storage
 state: ONLINE
  scan: none requested
config:

	NAME        STATE     READ WRITE CKSUM
	storage     ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    sdb     ONLINE       0     0     0
	    sdc     ONLINE       0     0     0

Verify dataset properties and compression ratio:

$ sudo zfs get all storage/backup | head -20
NAME            PROPERTY                VALUE    SOURCE
storage/backup  type                    filesystem default
storage/backup  creation                Mon Jun 27 10:30:00 2026
storage/backup  used                    100K     -
storage/backup  available               50G      -
storage/backup  referenced              96K      -
storage/backup  compressratio           1.45x    -
storage/backup  compression             lz4      local

Test write and read performance:

$ sudo dd if=/dev/zero of=/storage/backup/testfile bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.523 s, 200 MB/s

$ sudo ls -lh /storage/backup/testfile
-rw-r--r-- 1 root root 100M Jun 27 10:35 testfile

$ sudo rm /storage/backup/testfile
Tip: Use zpool iostat to monitor disk I/O in real-time

Troubleshooting Common Issues

Error: "module: No such file or directory"

If you see modprobe: FATAL: Module zfs not found in directory..., the kernel module isn't compiled or DKMS failed. Fix this:

$ sudo apt install build-essential dkms linux-headers-$(uname -r)
$ sudo dkms install zfs/

Error: "cannot open device /dev/sdb: Device busy"

This means the disk is already in use by another process (mounted or used for swap). Check and free the device:

$ lsblk /dev/sdb
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb    8:16   0 100G  0 disk

$ sudo umount /dev/sdb*
$ sudo swapoff /dev/sdb

Clear the disk's partition table before creating a zpool:

$ sudo sgdisk -Z /dev/sdb
The operation has completed successfully.

Error: "zpool status: no pools available"

The pool wasn't created or isn't mounted. Check and recreate:

$ sudo zpool list
no pools available

$ sudo zpool import  # Try importing old pools
$ sudo zpool create storage mirror /dev/sdb /dev/sdc

Error: "pool or dataset does not exist"

The dataset you're looking for doesn't exist. List all datasets or create a new one:

$ sudo zfs list -t filesystem
NAME      USED  AVAIL  REFER  MOUNTPOINT
storage   1.5M   200G    96K  /storage

$ sudo zfs create storage/newdataset

Frequently Asked Questions

Does ZFS consume a lot of RAM?

Yes, ZFS uses RAM for ARC (Adaptive Replacement Cache), which caches frequently read data. On a typical VPS, expect 1-8 GB depending on dataset count and pool size. You can limit ARC by editing /etc/modprobe.d/zfs.conf and adding options zfs zfs_arc_max=4294967296 (4 GB in this example).

Should I use smaller or larger record block sizes?

Default record size is 128K. Smaller blocks (4K-16K) work better for varied files like databases, while larger blocks (256K-1M) suit video and image files. Set recordsize when creating the dataset: sudo zfs create -o recordsize=16K storage/database

Can I delete a pool without losing other data?

Yes, use zpool destroy to delete a pool and all its data. This operation is irreversible, so ensure you have backups: sudo zpool destroy storage