Introduction
ZFS (Zettabyte File System), ported from OpenSolaris to Linux:
- SHA-256 checksums on every block (silent data corruption detection)
- Near-instant snapshots and clones
- Transparent compression (LZ4, ZSTD, gzip)
- Deduplication (optional, RAM-intensive)
- RAID-Z (RAID5/6 without the "write hole")
- Async replication (
zfs send/zfs receive) - Virtual volumes (ZVOL) for iSCSI/VM
- Practical limits: 256 zettabytes
Use cases: file servers, backup, VM storage, NAS, datalakes.
Prerequisites
- Linux VPS / server Debian 12 / Ubuntu 24.04
- 8 GB RAM minimum (ZFS loves RAM)
- Root access
- At least 2 disks (or partitions) for mirrors/RAIDZ
Step 1: Installation
Ubuntu (native since 20.04)
sudo apt update
sudo apt install -y zfsutils-linux
zfs version
Debian (contrib repo)
sudo nano /etc/apt/sources.list
# Add "contrib" to main lines
sudo apt update
sudo apt install -y zfs-dkms zfsutils-linux
sudo modprobe zfs
zfs version
Step 2: List disks
lsblk
sudo fdisk -l
Identify empty disks. Use /dev/disk/by-id/ for stability:
ls -lh /dev/disk/by-id/
Step 3: Simple pool
sudo zpool create datapool /dev/disk/by-id/ata-WDC_WD20EFRX_xxx
sudo zpool status
sudo zfs list
Pool datapool auto-mounts at /datapool.
⚠️ For production, never create a pool on a single disk. Use mirror or raidz.
Step 4: Mirror (RAID1)
sudo zpool create datapool mirror \
/dev/disk/by-id/ata-WDC_WD20EFRX_aaa \
/dev/disk/by-id/ata-WDC_WD20EFRX_bbb
Tolerates 1 disk loss, double read perf, same write as single.
Step 5: RAID-Z (RAID5)
For 4 disks with 1 parity (tolerates 1 dead disk):
sudo zpool create datapool raidz \
/dev/disk/by-id/ata-disk-1 \
/dev/disk/by-id/ata-disk-2 \
/dev/disk/by-id/ata-disk-3 \
/dev/disk/by-id/ata-disk-4
RAID-Z2 (RAID6, tolerates 2 disks):
sudo zpool create datapool raidz2 disk1 disk2 disk3 disk4 disk5 disk6
RAID-Z3 (3 parities) for 8+ disks.
Step 6: Datasets
A dataset = sub-FS in the pool with its own properties:
sudo zfs create datapool/home
sudo zfs create datapool/var
sudo zfs create datapool/backups
sudo zfs list
sudo zfs set compression=zstd datapool/backups
sudo zfs set compression=lz4 datapool/home
sudo zfs set atime=off datapool
sudo zfs set recordsize=1M datapool/backups
sudo zfs set recordsize=16K datapool/var/lib/mysql
Step 7: Compression
sudo zfs set compression=lz4 datapool
sudo zfs get compression,compressratio datapool
LZ4: fast, free CPU. ZSTD: better compression, more CPU. For cold data, ZSTD-19:
sudo zfs set compression=zstd-19 datapool/archives
Step 8: Snapshots
sudo zfs snapshot datapool/home@before-update
sudo zfs list -t snapshot
Instant, COW, space-efficient. Thousands possible.
Rollback:
sudo zfs rollback datapool/home@before-update
⚠️ Destroys later changes.
Read-only access:
ls /datapool/home/.zfs/snapshot/before-update/
Clone:
sudo zfs clone datapool/home@before-update datapool/home-test
Delete:
sudo zfs destroy datapool/home@before-update
Step 9: Replication (zfs send/receive)
sudo zfs snapshot datapool/home@2026-05-17
sudo zfs send datapool/home@2026-05-17 | ssh root@backup-server "zfs receive backuppool/home"
Incremental:
sudo zfs send -i datapool/home@2026-05-16 datapool/home@2026-05-17 | ssh root@backup-server "zfs receive backuppool/home"
For auto replication, use sanoid + syncoid:
sudo apt install -y sanoid
sudo nano /etc/sanoid/sanoid.conf
[datapool/home]
use_template = production
[template_production]
hourly = 36
daily = 30
monthly = 6
yearly = 3
autosnap = yes
autoprune = yes
sudo systemctl enable --now sanoid.timer
syncoid --recursive datapool/home root@backup:backuppool/home
Step 10: ARC tuning
ZFS uses RAM cache (ARC). Default: up to 50% RAM.
sudo nano /etc/modprobe.d/zfs.conf
options zfs zfs_arc_max=4294967296 # 4 GB in bytes
options zfs zfs_arc_min=1073741824 # 1 GB
sudo update-initramfs -u
sudo reboot
Monitor:
arc_summary
sudo cat /proc/spl/kstat/zfs/arcstats
Step 11: Maintenance and scrub
Scrub = full integrity check.
sudo zpool scrub datapool
sudo zpool status datapool
Monthly cron:
0 2 1 * * /usr/sbin/zpool scrub datapool
sudo zpool status -v datapool
ZFS auto-repairs detected errors if enough redundancy.
Step 12: Advanced operations
Hot spare
sudo zpool add datapool spare /dev/disk/by-id/ata-new-disk
Replace dead disk
sudo zpool replace datapool old-disk new-disk
L2ARC cache (SSD)
sudo zpool add datapool cache /dev/disk/by-id/nvme-cache-disk
SLOG for ZIL (NVMe)
sudo zpool add datapool log /dev/disk/by-id/nvme-slog
Useful for sync workloads (databases, NFS).
Export / import
sudo zpool export datapool
sudo zpool import datapool
sudo zpool import -d /dev/disk/by-id/ datapool
Troubleshooting
Pool DEGRADED
sudo zpool status -v
sudo zpool replace datapool /dev/disk/by-id/bad-disk /dev/disk/by-id/new-disk
sudo zpool status # watch resilver
"out of memory"
ARC too big. Limit zfs_arc_max.
Degraded performance
zpool iostat -v datapool 5
Check slow disk (high latency). Consider SLOG or L2ARC.
Pool lost after reboot
sudo zpool import
sudo zpool import datapool
sudo systemctl enable zfs-import-cache.service zfs-mount.service
Quota reached
sudo zfs set quota=50G datapool/home
sudo zfs set quota=none datapool/home # remove
Useful commands
sudo zpool create / destroy / status / import / export
sudo zpool list
sudo zpool iostat -v 5
sudo zpool scrub datapool
sudo zfs create datapool/foo
sudo zfs destroy datapool/foo
sudo zfs list
sudo zfs list -t snapshot
sudo zfs get all datapool/foo
sudo zfs snapshot datapool/foo@snap1
sudo zfs rollback datapool/foo@snap1
sudo zfs clone datapool/foo@snap1 datapool/foo-clone
sudo zfs send datapool/foo@snap1 | ssh remote zfs receive otherpool/foo
sudo zfs send -i @snap1 datapool/foo@snap2 | ssh remote zfs receive otherpool/foo
arc_summary
sudo zpool history
sudo zfs get compressratio datapool
sudo cat /proc/spl/kstat/zfs/arcstats | grep size
Conclusion
ZFS is the Linux storage Swiss Army knife:
- Integrity (checksums + scrub)
- Instant snapshots / replication
- Compression / dedup
- Robust RAID-Z
Limits:
- RAM-hungry (1 GB per TB recommended)
- CDDL license incompatible with GPL (not in mainline Linux kernel)
- No pool shrink
Going further:
- Use sanoid/syncoid for auto snapshots and replication
- Combine with TrueNAS Scale for full UI and turnkey NAS
- For max perf, add SLOG NVMe + L2ARC SSD
Resources
- OpenZFS docs: https://openzfs.github.io/openzfs-docs/
- GitHub: https://github.com/openzfs/zfs
- Sanoid / Syncoid: https://github.com/jimsalterjrs/sanoid
- TrueNAS Scale: https://www.truenas.com/truenas-scale/


















