The short version of ZFS snapshots explained for beginners: a snapshot is a read-only, point-in-time copy of a dataset that ZFS creates almost instantly and that starts out using zero extra space, because ZFS never overwrites live data in place. It undoes deleted files and bad edits in seconds. It is not a backup, because it lives on the same disks.
The rest is detail: how that space grows, how to get files back, and the one command that can wipe a month of history. Most people misconfigure snapshots by keeping everything forever, then wonder at month nine why deleting a terabyte of old downloads freed nothing.
What is a ZFS snapshot, actually?
A ZFS snapshot is a frozen, read-only view of a dataset or zvol at the moment you took it. The OpenZFS concepts page says snapshots “can be created extremely quickly, and initially consume no additional space within the pool.” Nothing is copied when you take one.
That works because ZFS is copy-on-write. When you edit a file, ZFS writes the changed blocks somewhere new and updates its pointers. Normally the old blocks get freed. A snapshot is a marker on the old pointer tree that says “keep these.” The live dataset moves on; the snapshot keeps pointing at the blocks as they were.
Two details from the zfs-snapshot man page matter early:
- Snapshots are atomic. A snapshot includes every write that had completed when it was taken, and nothing after.
- Recursive snapshots share one instant.
zfs snapshot -rcovers a dataset and all its children at the same moment, so parent and child agree on what time it is.
Recovery differs by type. A dataset snapshot can be browsed file by file; a zvol snapshot is a whole virtual disk you clone or roll back as a unit. Datasets vs zvols on TrueNAS explains which one holds your data.
How much space does a ZFS snapshot use?
A snapshot uses no space when it is created, then grows as the live dataset overwrites or deletes blocks the snapshot still references, because those blocks can no longer be freed. A snapshot of a dataset nobody touches stays near zero for years. A snapshot of a busy VM disk can grow fast.
Beginners get tripped up by how ZFS reports that space. Run zfs list -t snapshot -o name,used,refer and you get two columns that look like they should add up and don’t:
- REFER is how much data the snapshot can see: the dataset as it was at that moment.
- USED is space held by that one snapshot alone, roughly what destroying it by itself would give back.
The trap is in the fine print of zfsprops(7): space shared by multiple snapshots isn’t counted in any single snapshot’s USED. Say three nightly snapshots were taken while a 200 GB folder of movies existed, and then you delete the folder. Each snapshot shows a small USED, because the 200 GB is shared among all three, yet together they pin every byte of it. Destroy one and nothing comes back. Destroy all three and it does.
For the honest total, check the dataset’s usedbysnapshots property: the space that would be freed if every snapshot of it were destroyed. The written property shows how much has changed since the latest snapshot.
The commands you actually need
TrueNAS wraps all of this in the web UI, but ten minutes in the shell makes the model click. Pools mount under /mnt on TrueNAS, so tank/documents lives at /mnt/tank/documents.
# Take a snapshot; -r includes child datasets atomically
zfs snapshot tank/documents@before-cleanup
zfs snapshot -r tank@pre-upgrade
# List snapshots, oldest first
zfs list -t snapshot -o name,used,refer -s creation -r tank/documents
# What changed since? (- removed, + created, M modified, R renamed)
zfs diff tank/documents@before-cleanup
# Copy one file back out of the hidden snapshot directory
cp /mnt/tank/documents/.zfs/snapshot/before-cleanup/taxes/2025.pdf /mnt/tank/documents/taxes/
# Delete, with a verbose dry run first
zfs destroy -nv tank/documents@before-cleanup
zfs diff is the fastest answer to “what did that script just do to my files?” Before an OS upgrade, add a hold to the snapshot you care about (zfs hold keep plus the snapshot name); while it exists, zfs destroy fails with EBUSY. zfs-destroy also accepts a percent-sign range for clearing a run of old snapshots at once, which is exactly why the -n dry run comes first.
How do you restore a file from a ZFS snapshot?
Copy it out of the hidden .zfs/snapshot directory at the root of the dataset. Every snapshot appears there as a read-only folder tree, mounted on demand, so restoring one file is an ordinary copy and no rollback is needed. On Windows clients, the Previous Versions tab does the same job without a shell.
There are three routes, from least to most invasive.
The .zfs directory. It is hidden by default; the snapdir property controls that, and TrueNAS exposes it as Snapshot Directory in a dataset’s Advanced Options. One sharp edge from the TrueNAS 25.04 snapshot docs: a snapshot’s files are not accessible or searchable if the snapshot mount path is longer than 88 characters. Keep dataset names short.
Windows Previous Versions. The SMB share option Enable Shadow Copies exports ZFS snapshots as shadow copies for Windows VSS clients, and the TrueNAS share settings reference shows it on in the default preset. Right-click a folder, open Previous Versions, drag the old file out. The SMB share setup guide covers the share side.
Clone to a new dataset. A clone is a writable dataset built from a snapshot, created nearly instantly and initially using no extra space. TrueNAS offers Clone to New Dataset on the Snapshots screen and recommends cloning over rollback when you need an old state back. Pull out what you need, then delete the clone: a snapshot cannot be destroyed while a clone depends on it.
When should you roll back a snapshot?
Roll back only when you want the entire dataset returned to that moment and accept losing every change written since. Per zfs-rollback(8), all data changed after the snapshot is discarded. By default ZFS only rolls back to the most recent snapshot; going further back needs -r, which destroys every newer snapshot on the way.
Running zfs rollback -r against a September 1 snapshot to undo a bad app update also deletes every hourly snapshot taken since. TrueNAS adds that rollback “causes any configured replication tasks to fail,” so you will be fixing replication next.
The good use case is narrow: an app’s data lives in its own dataset, an upgrade mangles its config, and you want it back to last night. That only works when each app gets its own dataset, as in TrueNAS SCALE Docker apps. For “I deleted one folder,” never roll back. Copy from .zfs instead.
How to automate snapshots in TrueNAS
Go to Data Protection > Periodic Snapshot Tasks and click Add. Pick the dataset, tick Recursive to snapshot each child dataset too, list children to skip under Exclude, set a Snapshot Lifetime, and choose a schedule. The default naming schema is auto-%Y-%m-%d_%H-%M, per the Periodic Snapshot Tasks screen reference.
The TrueNAS periodic snapshot tutorial notes that snapshots as often as every 15 minutes are common, even on large, active pools. Lifetime is enforced lazily: it is how long cleanup ignores a snapshot, so one can outlive its lifetime until the next pruning run. For a one-off snapshot, select the dataset on the Datasets screen and use Create Snapshot in its Data Protection widget.
A sensible start: hourly snapshots kept two weeks on documents and app data, daily kept a month on photos, weekly on bulk media, and none on scratch or downloads. Snapshotting a torrent folder hourly is the fastest way to fill a pool with blocks you deliberately deleted. The full retention table, and how to ship it to a second box, is in the snapshot and replication strategy guide.
One caveat for databases and VMs: a snapshot captures what had reached disk, like pulling the power cord at that instant. For a database you would genuinely miss, stop the app or take its own dump first.
Why isn’t a ZFS snapshot a backup?
Because a snapshot lives on the same pool as the data it protects. Lose the pool to too many failed disks, a fire, theft or a mistyped zfs destroy -r, and every snapshot goes with it. Snapshots protect against you, your scripts and your users. Only a copy on a different machine protects against losing the machine.
Parity does not change that; RAIDZ1 vs RAIDZ2 is about surviving dead disks, not mistakes. The good news is that snapshots are the foundation of a real backup: ZFS replication sends snapshots, and after the first run only the changed blocks, to another pool. Get snapshots right now and replication becomes a small next step.
Snapshots carry one ransomware-shaped benefit: they are read-only, so a Windows PC encrypting files over SMB cannot rewrite the snapshot copies. Anyone with admin access to the NAS can still delete them, which is one more argument for that second box.
FAQ
Do ZFS snapshots slow down a NAS?
In normal home use, no. Creating a snapshot copies no data, and reads and writes to the live dataset carry on as before. The real costs are pool space held by old blocks and cleanup: TrueNAS notes that deleting snapshots in bulk is I/O intensive and can take a long time, especially with deduplication enabled.
Is it safe to delete old ZFS snapshots?
Yes. Destroying a snapshot never changes the live dataset; it only frees blocks that no other snapshot or the dataset itself still references. ZFS refuses to destroy a snapshot that has a hold or a dependent clone. Run zfs destroy with the -nv flags first to preview exactly what would be removed before committing.
Do ZFS snapshots include child datasets?
Only if you ask. A plain snapshot covers one dataset; child datasets need the -r flag on the command line or the Recursive checkbox in TrueNAS. Recursive snapshots are taken at the same instant, so every child gets a matching snapshot with the same name, and the Exclude field lets you skip throwaway children.
Related across the network
- TrueNAS Snapshot Schedule Best Practices for a Home NAS — truenashub.com
- How to Set Up an iSCSI Target on TrueNAS: Zvol to Login — iscsihub.com