Going deep into advanced ZFS: dataset encryption with AES-256-GCM, pool maintenance with scrub and clear, and monitoring with zpool events and iostat. You will also learn incremental replication with zfs send/receive plus the sanoid and syncoid tools for automated offsite backups.

In the previous episode 8, you mastered the foundations of ZFS: pools, datasets, snapshots, and boot environments. Now we level up to advanced ZFS: encryption, pool maintenance, and replication — the three pillars that separate storage that merely "runs" from storage that's production-ready.
Encryption protects your data when media is lost or stolen. Scrub ensures the data you read is truly intact. Replication guarantees your data survives even when the primary machine is destroyed. Let's break down all three.
ZFS supports native per-dataset encryption with modern algorithms. The strong default choice is AES-256-GCM. Data is encrypted before being written to disk, and the key is stored separately — without the key, the data remains fully encrypted.
The key is set when the dataset is created, via a passphrase:
zfs create -o encryption=aes-256-gcm -o keyformat=passphrase tank/secretAfter a reboot, the dataset is not mounted automatically because the key hasn't been loaded. You need to load the key first:
zfs load-key tank/secret
zfs mount tank/secretInfo
ZFS encryption is per dataset, not per pool. You can mix encrypted and unencrypted datasets in one pool. Remember: child datasets inherit the encryption property from their parent unless explicitly overridden.
To load the key at boot, use zfs load-key -L with a mounted key location:
zfs load-key -L file:///root/keys/secret.key tank/secretA safe alternative is loading the key interactively from the console at boot. Never store the passphrase in the same dataset as the data it encrypts.
Encryption works seamlessly with snapshots and replication — snapshots of an encrypted dataset remain encrypted, and zfs send transmits encrypted data. The data on the receiving side stays protected until the key is loaded.
Danger
If the passphrase key is lost, ZFS-encrypted data cannot be recovered by any means. Store the key or passphrase in a secure location separate from the system, and test key recovery periodically.
zpool status is the first command when you suspect a problem:
zpool statusPay attention to the STATE column and the READ/WRITE/CKSUM columns. Non-zero values indicate potential disk or cable problems.
A scrub reads all data in the pool and compares it against checksums:
zpool scrub tank
zpool statusA scrub finds bit-rot before corrupted data gets used. Schedule periodic scrubs — for example monthly — and monitor the results.
Success
A scrub is health insurance for your data. ZFS can repair damage automatically if there's redundancy (mirror or RAID-Z); without redundancy, a scrub at least tells you early that there's a problem.
If zpool status shows transient errors, clear them with zpool clear:
zpool clear tankIf a disk is genuinely broken, replace it with zpool replace:
zpool replace tank /dev/ada1 /dev/ada4After the replacement, ZFS automatically resilvers (rebuilds) the data onto the new disk. Don't rush to cut power while a resilver is running.
zpool events displays ZFS event history for diagnosis:
zpool events
zpool events -v | tail -20And for I/O performance statistics:
zpool iostat -v tank 1
zfs listzfs send sends a snapshot, and zfs receive receives it. For efficient transfers, send only the difference between snapshots:
zfs snapshot tank/data@daily
zfs send -i tank/data@yesterday tank/data@daily | ssh backup zfs receive backup/data-i (incremental) sends only the changes between the yesterday and daily snapshots. This dramatically saves bandwidth and time for large data.
Often replication targets a backup machine in another location:
zfs send tank/data@baseline | ssh backup "zfs receive -F backup/data"Set up SSH keys for the backup host so the process runs non-interactively. For extra security, enable the readonly=on property on the target dataset.
Creating snapshots and replication manually is tedious. Sanoid automates scheduled snapshots, and syncoid makes replication easy:
pkg install sanoidSanoid is configured through /usr/local/etc/sanoid/sanoid.conf. An example for the tank/data dataset:
[tank/data]
frequent = 12
hourly = 24
daily = 7
monthly = 3And replication with syncoid:
syncoid tank/data backup:/backup/dataInfo
The combination of sanoid for local snapshots, syncoid for remote replication, and monthly scrubs forms a solid backup strategy: your data always has versions, always has an offsite copy, and its integrity is always verified.
In this episode 9, you went deep into advanced ZFS: AES-256-GCM dataset encryption with load-key and mount, pool maintenance with scrub, clear, and replace, monitoring with events and iostat, incremental replication with zfs send -i, and automation with sanoid and syncoid.
Key takeaways:
zpool replace.zfs send -i saves bandwidth for daily backups.In the next episode, episode 10, we'll cover networking & network configuration — interface configuration in rc.conf, the ifconfig and route commands, resolv.conf, plus advanced features like VLANs, lagg, bridges, jumbo frames, and an introduction to the pf and ipfw firewalls.