| pick your distro, get ZFS on root
kldload — your platform, your way, free
Source

Clone Anything

Instant copies in milliseconds — not minutes. ZFS clones let you duplicate datasets, VM disks, and home directories at near-zero cost.

The short version: a ZFS clone is an instant, read-write copy of a dataset that starts by sharing all the original data. No bytes are duplicated until something actually changes. A 100 GB dataset clones in under a second and costs almost nothing until you start modifying the copy.

Why clones are different from copies

The old way — cp -r

Reads every file from disk, writes a full duplicate. A 100 GB dataset takes 5–20 minutes, uses 100 GB more disk space immediately, and the copy starts from scratch every time.


cp -r /data /data-copy
# 15 minutes later...
# -rw-r--r-- 100GB /data-copy

The ZFS way — zfs clone

Creates a new dataset that points to the same blocks. No data is copied. Instant at any size. The clone only uses space for blocks that differ from the original — everything else is shared.


zfs snapshot rpool/data@now
zfs clone rpool/data@now rpool/data-copy
# Done in < 1 second.

Copy-on-Write (CoW) — the magic behind it

ZFS uses a technique called Copy-on-Write. When you clone a dataset, both the original and the clone point to the same physical blocks on disk. When you write to the clone, ZFS writes the new data to a new block and updates only the clone's pointer. The original is never touched. This is why a clone is instant — nothing is actually copied until something changes.

analogy: a shared Google Doc where everyone reads the same document. when you make edits, a private copy of those pages is made just for you. the original stays untouched.

Clone a dataset

The basic pattern is always the same: take a snapshot, then clone from that snapshot. This is a fundamental ZFS rule — you cannot clone a dataset directly; you must clone from a snapshot. kldload's kclone wrapper hides this step from you; the native commands make it explicit.

# The kldload way — snapshot + clone in one command
kclone /data /data-copy
# The native ZFS way — two explicit steps
# Step 1: Take a snapshot (required — clones must come from a snapshot)
zfs snapshot rpool/data@before-test

# Step 2: Clone it — this is instant regardless of size
zfs clone rpool/data@before-test rpool/data-copy

# Step 3: Verify both exist
zfs list rpool/data rpool/data-copy

Why does native ZFS require a snapshot first?

A ZFS clone is defined as a writable snapshot. There is no way to clone a live dataset in one atomic operation — you must freeze a point in time (the snapshot) and clone from that frozen state. The snapshot becomes the shared ancestor that both the original and the clone inherit their data from. kclone takes the snapshot automatically before cloning, which is why you don’t have to think about it.

NAME               USED  AVAIL  REFER  MOUNTPOINT
rpool/data        78.3M   412G  78.3M  /rpool/data
rpool/data-copy    192K   412G  78.3M  /rpool/data-copy

Notice: data-copy shows only 192K used — that's just metadata. The 78.3 MB of actual data is shared with the original and counted once.


Clone a VM disk

This is one of the most useful things you can do. Create a "golden" VM image once, then clone it to spin up new VMs instantly:

# The kldload way
kclone /vms/golden /vms/test-vm-1
kclone /vms/golden /vms/test-vm-2
# The native ZFS way
# Take a snapshot of the golden VM disk
zfs snapshot rpool/vms/golden@ready

# Clone it to create a new test VM — instant
zfs clone rpool/vms/golden@ready rpool/vms/test-vm-1

# Clone it again for another VM — still instant (clones from same snapshot)
zfs clone rpool/vms/golden@ready rpool/vms/test-vm-2

Each clone starts as a full copy of the golden image, but uses almost zero extra disk space until the VMs diverge. This is how you can spin up 10 VMs in the time it used to take to copy one disk image.

# Check how much space each VM actually uses vs references
zfs list -o name,used,refer rpool/vms
NAME                   USED  REFER
rpool/vms              20.1G  96K
rpool/vms/golden       20.0G  20.0G
rpool/vms/test-vm-1     312K  20.0G
rpool/vms/test-vm-2     204K  20.0G

REFER is what the dataset sees (the full 20 GB image). USED is what it actually owns on disk (just the changes so far). The golden image is stored once.


Clone a user's home directory

Useful for testing, creating sandbox environments, or giving a user a safe copy to experiment in:

# The kldload way — finds the ZFS dataset for the path, snapshots, and clones
kclone /home/admin /home/admin-backup
kclone /home/admin /home/admin-test
# The native ZFS way
# Snapshot the current state of admin's home
zfs snapshot rpool/home/admin@2026-03-26

# Clone it as a backup the user can browse
zfs clone rpool/home/admin@2026-03-26 rpool/home/admin-backup

# Or clone it as a separate sandbox
zfs clone rpool/home/admin@2026-03-26 rpool/home/admin-test

# Set permissions on the copies so the user owns them
chown -R admin:admin /rpool/home/admin-backup

The cloned home directory is fully writable. The user can delete, modify, or break things in their test copy without affecting their real home directory.

What kclone adds over zfs snapshot + zfs clone

Path resolution — you give it a filesystem path (/home/admin); it figures out the ZFS dataset name (rpool/home/admin). With native ZFS you need to know the dataset name.
Automatic snapshot — no need to run zfs snapshot first; kclone does it immediately before cloning so the two steps are atomic from your perspective.
One command instead of two — less chance of cloning an outdated snapshot by accident.
Works for any pathkclone /srv/production /srv/staging or kclone /var/lib/postgres /var/lib/postgres-test without knowing the underlying ZFS layout.


Clean up when you're done

Clones are just datasets — delete them with zfs destroy when you no longer need them:

# Delete a clone
zfs destroy rpool/data-copy

# If the clone has its own snapshots, add -r to remove those too
zfs destroy -r rpool/vms/test-vm-1

One rule: you can't delete the snapshot while clones depend on it

The original snapshot (rpool/data@before-test) must exist as long as clones depend on it. If you try to delete it, ZFS will refuse. You can either delete the clone first, or use zfs promote to make the clone independent — then the original becomes the dependent instead.

zfs promote rpool/data-copy # makes the clone the "real" dataset

Quick reference

Clone any dataset — kldload way

One command. kclone resolves the path, snapshots, and clones.

kclone /path/to/source /path/to/copy

Clone any dataset — native ZFS

Two explicit steps. You supply the dataset name, not the path.

zfs snapshot rpool/data@snap
zfs clone rpool/data@snap rpool/data-copy

See how much space clones use

USED = unique blocks this clone owns. REFER = total data it sees (shared + owned).

zfs list -o name,used,refer

Delete a clone

Just like any other dataset. The original is unaffected.

zfs destroy rpool/data-copy

Make a clone independent (promote)

Reverses the parent-child relationship. The clone becomes the primary dataset; the original becomes the dependent.

zfs promote rpool/data-copy

kldload vs native — quick reference table

Task kldload Native ZFS What k* adds
Clone a dataset by path kclone /source /dest zfs snapshot ds@snap && zfs clone ds@snap ds-copy Path-to-dataset resolution, automatic snapshot, one step
Clone a VM disk kclone /vms/golden /vms/new-vm zfs snapshot rpool/vms/golden@ready && zfs clone rpool/vms/golden@ready rpool/vms/new-vm No need to know the ZFS dataset path for the VM disk
Check clone space usage (use native) zfs list -o name,used,refer No wrapper needed — zfs list is already readable
Delete a clone (use native) zfs destroy rpool/data-copy No wrapper needed — zfs destroy is direct
Make clone independent (use native) zfs promote rpool/data-copy No wrapper — zfs promote is a single clear command