% zelta-backup(8) | System Manager's Manual
NAME¶
zelta backup - replicate a ZFS dataset tree
SYNOPSIS¶
zelta backup [OPTIONS] source target
DESCRIPTION¶
zelta backup recursively replicates snapshots from a source ZFS dataset to a target dataset. Both source and target may be local or remote via ssh(1).
As with other Zelta commands, zelta backup works recursively on a dataset tree. The target dataset must be a replica of the source or must not exist.
Prior to replication, zelta backup analyzes both source and target to automatically select optimal zfs send and zfs recv options. This process includes property inspection, parent dataset creation if needed, snapshot GUID comparison via zelta match, and one or more send/recv operations to update the target.
Replication Process¶
zelta backup performs these operations:
- Property Analysis: Source and target properties are checked using
zfs getto detect encryption, written state, and other features. - Parent Creation: If the target dataset's parent does not exist, it will be created with
zfs create. - Snapshot Comparison: Using zelta match, a snapshot GUID comparison is performed with
zfs listto identify matching snapshots and determine the optimal replication strategy. - Snapshot Creation: If the source has uncommitted changes and no recent snapshot exists, a new snapshot is created (unless
--no-snapshotis specified). - Incremental Sync: One or more
zfs send/zfs recvoperations are performed to update the target, using incremental sends when possible.
Send Options¶
The following zfs send options are applied based on dataset properties:
- Default:
--raw(equivalent to-Lce) - Encrypted Datasets:
--raw - New/Full Syncs: Also includes
--props - Replicate Mode (
-R):--replicate,--large-block,--raw,--skip-missing
Target Safety Features¶
To ensure safe and repeatable replication, the following measures are applied to the target:
- The property
readonly=onis set on the topmost dataset requested - Synced filesystems are not mounted on the target during replication
- On newly backed up filesystems, property
canmount=noautois set - On newly backed up filesystems, mountpoints are inherited to prevent overlapping mounts
Source and Target Endpoints¶
Remote dataset endpoint names follow scp(1) conventions and require standard ZFS utilities and SSH access. Note that Zelta does not need to be installed on remote ZFS servers.
Examples:
Local: pool/dataset
Local: pool/dataset@snapshot
Remote: user@example.com:pool/dataset
Remote: user@example.com:pool/dataset@snapshot
IPv6: user@[2001:db8::1]:pool/dataset
OPTIONS¶
Endpoint Arguments (Required)¶
If both endpoints are remote, the default behavior is pull replication (--pull). This requires that the target user have ssh access to the source, typically provided by ssh keys or agent forwarding. For advanced ssh configuration, see https://zelta.space.
- source
- The dataset to replicate. If a snapshot is specified, replication will sync up to that snapshot.
- target
- The dataset which will be updated.
Output Options
- -v, --verbose
- Increase verbosity. Specify once for operational detail, twice (
-vv) for debug output. - -q, --quiet
- Decrease log level. Specify once to suppress notices, twice (
-qq) to suppress warnings. - -j, --json
- Output results in JSON format. See zelta-options(7) for details.
- -n, --dryrun, --dry-run
- Display
zfscommands without executing them.
Connection Options¶
- --push, --pull, --sync-direction DIRECTION
- When both endpoints are remote, use
PULL(default) orPUSHsync direction. - --recv-pipe COMMAND
- Pipe
zfs receiveoutput through the indicated command, such asdd status=progress.
Dataset Options¶
- -d, --depth LEVELS
- Limit recursion depth. For example, a depth of 1 includes only the specified dataset.
- --exclude, -X PATTERN
- Exclude /dataset/suffix, @snapshot, or #bookmark beginning with the indicated symbol. Wildcards
?and*are permitted. See zelta-match(8). - --include PATTERN
- Only include /dataset/suffix, @snapshot, or #bookmark beginning with the indicated symbol. Wildcards
?and*are permitted. See zelta-match(8).
Snapshot Options¶
- --no-snapshot
- Do not create snapshots. If a snapshot is needed for replication, the operation will fail.
- --snapshot, --snapshot-always
- Force snapshot creation even if the source has no uncommitted changes.
- --snap-name NAME
- Specify snapshot name. Use
$(command)for dynamic generation. Default:$(date -u +zelta_%Y-%m-%d_%H.%M.%S). - --snap-prefix PREFIX
- Prefix generated snapshot names. If the resolved name starts with
zelta, PREFIX replaceszelta; otherwise PREFIX is prepended verbatim. Example:--snap-prefix=daily --include='@daily*'. - --snap-mode MODE
- Specify when to snapshot:
NEVER(or0),IF_NEEDED(default, only if source has new data or no recent snapshot), orALWAYS. - --snap-time DURATION
- In
IF_NEEDEDmode, skip snapshot creation if every source dataset has a recent enoughsnapshots_changedtimestamp. Bare numbers are Unix epoch seconds and are compared directly. Relative values use the same unambiguous duration syntax as zelta-prune(8):seconds,minutes,hours,days,weeks,months, oryearsmay be abbreviated to any unambiguous prefix. The unitsmandMare invalid because they are ambiguous between minutes and months. Examples:--snap-time 1715200000,--snap-time 8h,--snap-time '30 minutes'. - --snap-size SIZE
- In
IF_NEEDEDmode, skip snapshot creation if cumulative source writes are below the threshold. Bare numbers are bytes; supported suffixes areK,M,G,T,P, andE. Example:--snap-size 128K.
--snapshot and --no-snapshot ignore --snap-time and --snap-size.
Bookmark Options¶
- --bookmark
- After a successful receive, create a ZFS bookmark on each confirmed source snapshot. Default is off.
- --no-bookmark
- Do not create source bookmarks after replication (default).
- --bookmark-prefix PREFIX
- Prefix for bookmark names. Default is
{targethost}_, producing names such aspool/ds#backuphost_snapname.
Sync Options¶
- --target-origin, --origin TARGET_ORIGIN
- Back up an existing clone by using the source clone's detected origin snapshot as the incremental basis and setting the receive origin on the target. For example,
zelta backup --target-origin=cpool/treetop apool/treetop1234 cpool/treetop1234sends from the source clone origin and receives with-o origin=cpool/treetop@.... - -R, --replicate
- Use
zfs send --replicateinstead of Zelta's per-snapshot analysis. This sends all snapshots, bookmarks, and properties in a single process but provides less granular control over send options. - -I
- Sync all intermediate source snapshots using
zfs send -Ifor updates. This is the default behavior. See -i. - -i, --incremental
- Sync only the latest snapshot, skipping any intermediate snapshots. For full backups only the latest snapshot will be sent. For incremental backups,
zfs send -iwill be used. - --resume, --no-resume
- Enable (default) or disable automatic resume of interrupted syncs.
- --send-check
- Attempt to detect and drop Zelta's default
zfs sendoptions (-L,-c,e) if the source does not support them.
Advanced Override Options¶
WARNING: These options override Zelta's automatic safety and efficiency logic. Incorrect usage can result in target data loss or decrypted backup streams. Use only when you understand the implications.
Zelta automatically applies non-destructive and efficient zfs send and zfs recv options based on dataset type and context. These defaults can be modified three ways:
- Granular Override Options — Override specific contexts (encrypted vs unencrypted, filesystem vs volume, etc.)
- Dataset Tree Override Options — Replace all
zfs sendorzfs recvoptions for an entire backup job - Pass-Through Override Flags — Directly pass unambiguous
zfs sendorzfs recvflags
Most Common Use Case: Recompress Backups
Typically, users adjust Zelta options because they would like to aggressively compress data on their backup endpoints. This is best done with the --send-default and --recv-default flags, which will not prevent Zelta from sending encrypted backups in raw (encrypted) format:
zelta backup --send-default -Le --recv-default '-o compression=zstd-5' source backup
All overrides can also be configured globally in zelta.env or per-job via zelta.conf.
Important: Options with Special Handling¶
Several zfs send and zfs recv options have special meaning in Zelta and should generally not be included in override strings:
Zelta uses these internally:
- zfs send --parsable (-P) — Used for progress tracking
- zfs recv -v — Used for operational feedback
These have Zelta-specific behavior (see OPTIONS above):
- -I and -i — Control incremental behavior; use the flags documented above instead
- --include, --exclude, -X — Can be used to skip snapshots during a backup, such as only send snapshots matching '@daily*'.
- --dryrun, -n — Shows commands that would run; handled by Zelta
- -t — Used automatically for resume tokens
Not supported:
- zfs send -S — Unsupported
- zfs recv -A — Should be used manually when needed
Granular Override Options¶
For precise control in a dataset tree with mixed types, override specific contexts. These options are cumulative—for example, a filesystem receive will combine options from --recv-default, --recv-top (if applicable), and --recv-fs.
- --send-default "OPTIONS"
zfs sendoptions for unencrypted datasets (default:--raw, equivalent to-Lce)- --send-decrypted "OPTIONS"
zfs sendoptions for encrypted datasets when raw incremental send is unavailable (default:-Lc). This sends a decrypted stream with large blocks and preserves existing send-stream compression. Use-Linstead when you want the receiving side to recompress or encrypt from plaintext.- --send-raw "OPTIONS"
zfs sendoptions for encrypted datasets (default:--raw)- --send-new "OPTIONS"
- Additional
zfs sendoptions during full (non-incremental) backups (default:-p) - --recv-default "OPTIONS"
zfs recvoptions for all datasets (none by default)- --recv-top "OPTIONS"
- Additional
zfs recvoptions for the topmost dataset only (default:-o readonly=on) - --recv-fs "OPTIONS"
- Additional
zfs recvoptions for filesystem datasets (default:-u -o canmount=noauto -x mountpoint) - --recv-vol "OPTIONS"
- Additional
zfs recvoptions for volume datasets (default:-o volmode=none)
Examples:
# Allow target to recompress unencrypted data
zelta backup --send-default "-Le" source target
# Change volume mode on target
zelta backup --recv-vol "-o volmode=dev" source target
# Avoid mountpoint permission issues on some systems
zelta backup --recv-fs "-o mountpoint=none" source target
Dataset Tree Override Options¶
These options replace all context-specific defaults for an entire backup job. Use when you need complete control over a specific command.
- --send-override "OPTIONS"
- Override all default
zfs sendoptions - --recv-override "OPTIONS"
- Override all default
zfs recvoptions
Example:
# Use minimal `zfs send` to send uncompressed (**and decrypted!**) streams and recompress aggressively on the target
zelta backup --send-override "-L" --recv-override "-o compression=zstd-5" source target
Pass-Through Override Flags¶
If any pass-through flag is specified, it replaces all automatic options for that command. For example, specifying -L alone means zfs send will receive only -L—no compression, no embedded data, no properties.
The following unambiguous zfs send and zfs recv flags are passed through directly:
zfs send: -b, --backup, --embed, --holds, -L, --largeblock, --proctitle, --props, --raw, --skipmissing, -V, -w
zfs recv: -F, -M, -u, -o, -x
Ambiguous or unsupported flags:
- Single-dash options with multiple meanings are not supported: -c, -d, -e, -h, -s
- Options with Zelta-specific handlers (see above): -I, -i, -R, -X, -n
Example:
# Recompress at target with zstd-5
# WARNING: This disables encrypted sends!
zelta backup -L -o compression=zstd-5 source target
When in doubt, use the granular override options instead.
EXAMPLES¶
The same command works for both new and existing target datasets.
Local replication with automatic snapshot creation:
zelta backup sink/source/dataset tank/target/dataset
Remote to local synchronization:
zelta backup remote_host:sink/source/dataset tank/target/dataset
Dry run to preview commands:
zelta backup -n sink/source/dataset tank/target/dataset
Replicate with custom snapshot naming:
zelta backup \--snap-name "backup_$(date +%Y%m%d)" \
sink/source/dataset tank/backups/source/dataset
Incremental sync, skipping intermediate snapshots:
zelta backup -i sink/source tank/target
Limit recursion depth:
zelta backup -d 2 sink/source tank/target
EXIT STATUS¶
Returns 0 on success, non-zero on error.
NOTES¶
See zelta-options(7) for environment variables, zelta.env configuration, and zelta policy integration.
The zelta sync command remains available for compatibility as a convenience alias for zelta backup -i. New scripts should prefer explicit zelta backup commands.
SEE ALSO¶
zelta(8), zelta-options(7), zelta-match(8), zelta-policy(8), zelta-clone(8), zelta-revert(8), zelta-rotate(8), zelta-snapshot(8), ssh(1), zfs(8), zfs-send(8), zfs-receive(8)
AUTHORS¶
Daniel J. Bell _bellhyve@zelta.space_
WWW¶
https://zelta.space