BTRFS-BACKUP-NG-SNAPPER(1)
π btrfs-backup-ng-snapper β like, the whole manual π
okay bestie, pull up a chair π«Ά this is the man page for btrfs-backup-ng-snapper, one of the btrfs-backup-ng user commands. It's the part of the toolkit that speaks fluent Snapper. Buckle up, it's long, we're doing this properly. β¨
β¨ NAME β¨
btrfs-backup-ng-snapper β back up and restore snapper-managed snapshots π
π SYNOPSIS π
btrfs-backup-ng snapper detect [--json]
btrfs-backup-ng snapper list [--config NAME] [--type TYPE] [--json]
btrfs-backup-ng snapper backup CONFIG TARGET [OPTIONS]
btrfs-backup-ng snapper restore SOURCE [--list | --snapshot NUM | --all]
[CONFIG]
btrfs-backup-ng snapper status [--config NAME] [--target PATH] [--json]
btrfs-backup-ng snapper generate-config [CONFIG...] [OPTIONS]
π DESCRIPTION π
So basically: this command backs up and restores snapshots that Snapper manages. It's the little integration bridge that lets btrfs-backup-ng vibe with your existing Snapper setups β and it keeps Snapper's metadata (info.xml) and directory structure intact the whole time. No cap. π₯
Snapper is the tool people use for managing btrfs snapshots, and it's everywhere on openSUSE, Fedora, and Arch Linux. So if you're already running Snapper for local snapshot management, this command is your bestie: it replicates those snapshots out to remote backup storage. πΈ
π SUBCOMMANDS π
π detect
Discover Snapper configurations on the system. Like a little recon mission. π΅οΈ
btrfs-backup-ng snapper detect [--json]
It scans /etc/snapper/configs/ for Snapper configurations and shows you their subvolumes, snapshot directories, and whether they're valid or not.
--jsonβ Output in JSON format for scripting. For when you need it machine-readable, iykyk. π€
π list
List snapshots for one config, or literally all of them.
btrfs-backup-ng snapper list [--config NAME] [--type TYPE]
[--json]
--config NAMEβ List snapshots only for the specified Snapper config. If you leave it out, it lists snapshots for all configs. π--type TYPEβ Filter by snapshot type. You can pass this more than once. Valid types are:single(standalone/timeline),pre(before package operations),post(after package operations).--jsonβ Output in JSON format.
π backup
Back up Snapper snapshots to a target location. The main event. β¨
btrfs-backup-ng snapper backup CONFIG TARGET [OPTIONS]
CONFIGβ Snapper configuration name (e.g.,"root","home").TARGETβ Destination path. For btrfs destinations, use a local path (e.g.,/mnt/backup/root) or SSH (e.g.,ssh://user@host:/backups/root). For non-btrfs destinations, use a raw target that writes a btrfs send stream to a file:raw:///path(local) orraw+ssh://user@host/path(remote). The target must exist and is not created; the.snapshotstree and each numbered slot are created below it (see PATHS inbtrfs-backup-ng(1)).
Options:
--snapshot NUMβ Back up only the specified snapshot number. Just the one. π―--type TYPEβ Filter by snapshot type. Can be specified multiple times.--min-age DURATIONβ Skip snapshots younger than the specified age. Format:30m,1h,1d. Super useful to avoid backing up incomplete pre/post pairs β like, wait for them to actually finish, babe. π--compress METHODβ Compression for remote transfers. Valid:none,zstd,gzip,lz4,pigz,lzop. Default:zstdfor SSH targets,nonefor local.--rate-limit RATEβ Bandwidth limit for transfers. Examples:10M,1G,500K. Be kind to your network π--ssh-sudoβ Usesudofor btrfs commands on the remote host (SSH /raw+sshtargets).--ssh-key FILEβ Path to SSH private key file.--ssh-auth-sock PATHβ Explicit ssh-agent socket (overrides auto-discovery; useful undersudo).--ssh-host-key-policy POLICYβ Host-key verification:accept-new(default) orstrict.--dry-runβ Show what would be backed up without making changes. Zero commitment, honestly iconic. π-v,--verboseβ Enable verbose output.--encrypt METHODβ Encrypt the backup (raw:///raw+ssh://targets only).--gpg-recipient KEYIDβ GPG recipient key (required with--encrypt gpg).--no-progressβ Disable progress bars (default when not in a terminal).--progressβ Show progress bars (default when running in a terminal).--skip-remote-lockβ Proceed even if a pin cannot be recorded on the backup location, wherever its lock store lives (a remote target's lock directory, or a local location's lock file). Only safe when nothing else can prune this location during the run. A medium mounted read-only needs no pin and none is asked for.--timestamp-format FMTβstrftimeformat for the timestamp in backup names (default:%Y%m%d-%H%M%S).
π restore
Restore Snapper snapshots from a backup location. Bring it back. π¦
btrfs-backup-ng snapper restore SOURCE [OPTIONS] [CONFIG]
SOURCEβ Backup location to restore from. Can be local or an SSH URL.CONFIGβ Local Snapper configuration name to restore into. Required to restore; optional with--list(listing only reads the source, no big deal).
Options:
-l,--listβ List available backups at the source location.--snapshot NUMβ Restore a specific snapshot number. Can be specified multiple times. On a reused (duplicate) snapper number, it restores the newest by date and warns you. π--backup-name NAMEβ Restore the exact raw backup by its unique name (shown by--list). Can be specified multiple times. Use this to reach an older copy when a snapper number was reused after a prune.--date DATEβ Restrict the selection to backups whose date matchesDATE(YYYY-MM-DD[ HH:MM:SS]prefix). Disambiguates a reused--snapshot.-a,--allβ Restore all available backups. Everything. All of it. π--ssh-sudoβ Usesudofor btrfs commands on the remote host (SSH /raw+sshtargets).--ssh-key FILEβ Path to SSH private key file.--ssh-auth-sock PATHβ Explicit ssh-agent socket (overrides auto-discovery; useful undersudo).--ssh-host-key-policy POLICYβ Host-key verification:accept-new(default) orstrict.--gpg-keyring PATHβ GPG keyring to decrypt an encrypted raw snapper backup. Must match the keyring the backup was encrypted for.--openssl-cipher CIPHERβ OpenSSL cipher fallback for a legacy raw backup whose.metasidecar does not record one. Modern sidecars are authoritative and override this.--dry-runβ Show what would be restored without making changes.--jsonβ Output in JSON format (with--list).--from-config NAMEβ Only restore from this snapper config in backup.
okay breathe, bestie, this next bit is the Big Paragraph and it matters, so read it slow πΈ
A restore is a transfer through the same planner and executor a backup uses, into Snapper's own layout. The selection is restored exactly as given, never expanded to a chain (--all selects everything). Each increment's parent is chosen from what the local config already holds, by identity (a slot's received_uuid against the identity the backup's stream carries), never by Snapper number: a backup whose parent is already restored is received as an increment from that copy, one whose parent is not there is received in full. Onto empty recovery media, --snapshot N is one full send into slot 1. Every selected backup lands in a NEW slot whether or not a copy is already there. The copy is received into .snapshots/{N}.incoming/, checked, given its renumbered info.xml, and only then renamed to .snapshots/{N}/, so a restore that fails mid-receive leaves no numbered slot and no temp. The number is decided when the copy is published, with a rename that cannot replace an existing entry: a snapshot Snapper creates while the restore runs keeps its slot and the copy lands under the next free number. One writer runs below a .snapshots tree at a time β a restore into a config, or a backup into a local target β and a second one started meanwhile is refused with the reason. The backup is pinned on its location for the duration (released if a transfer fails or the run is interrupted), and no prune deletes a pinned slot or stream, on any location type; --skip-remote-lock for a location that can be read but not written, and nothing for a medium mounted read-only. A raw:// increment whose parent is neither in the config nor selected is refused before anything is transferred. π
β οΈ A restored snapshot is written directly into.snapshots/{N}/(not viasnapper create), so the Snapper daemon does NOT see it until it reloads. Restart it (systemctl restart snapperd, as root) or reboot after a restore before usingsnapper diff,snapper undochange, or a rollback against it; the command prints a reminder. The on-disk snapshot is complete and correct β only the daemon's in-memory view lags, andsnapper listalone does not make it look again. Restored slots use Snapper's native0755directory mode.
For a raw+ssh:// source written with --ssh-sudo (root-owned remote directory), pass --ssh-sudo to restore as well, or it will report a permission error instead of the backups. When Snapper has reused a number after a prune, a raw target can hold two backups with the same number; --snapshot NUM restores the newest by date and warns. To restore an older copy, use --backup-name NAME (names are shown by --list) or narrow --snapshot NUM with --date YYYY-MM-DD.
π status
Show backup status for Snapper configurations. The vibe check. π
btrfs-backup-ng snapper status [--config NAME] [--target PATH]
[--json]
--config NAMEβ Show status for a specific config only.--target PATHβ Check backup status at the specified target. Shows which snapshots are backed up vs pending.--jsonβ Output in JSON format.
π generate-config
Generate TOML configuration for Snapper volumes. Let it cook. π
btrfs-backup-ng snapper generate-config [CONFIG...] [OPTIONS]
CONFIGβ Snapper configuration names to include. If omitted, it generates for all configs.
Options:
--target PATHβ Target path for backups. The config name will be appended (e.g.,/mnt/backupbecomes/mnt/backup/rootfor therootconfig).--type TYPEβ Snapshot types to include. Can be specified multiple times. Default:single.--min-age DURATIONβ Minimum snapshot age. Default:0.-o,--output FILEβ Write configuration to file.--append FILEβ Append to existing configuration file.--ssh-sudoβ Addssh_sudo = trueto SSH targets.--jsonβ Output in JSON format.
π BACKUP DIRECTORY LAYOUT π
Snapper backups preserve the native Snapper directory structure. Exactly like this, no notes:
/backups/root/.snapshots/
βββ 559/
β βββ info.xml # Snapper metadata
β βββ snapshot/ # btrfs subvolume
βββ 560/
β βββ info.xml
β βββ snapshot/
βββ 561/
βββ info.xml
βββ snapshot/
This layout enables direct restoration back into Snapper-managed volumes. That's the whole point, bestie. π«Ά
...more coming, don't go anywhere π
πΈ CONFIGURATION πΈ
okay so for automated backups you literally just add your Snapper volumes to your config.toml and it's giving effortless:
[[volumes]]
path = "/"
source = "snapper"
[volumes.snapper]
config_name = "root"
include_types = ["single", "pre", "post"]
min_age = "1h"
[[volumes.targets]]
path = "ssh://backup@server:/backups/root"
ssh_sudo = true
compress = "zstd"
then bestie you run:
btrfs-backup-ng run
periodt. that's the whole vibe. β¨
π Configuration Options π
config_nameβ the Snapper config name (like"root"or"home") OR"auto"if you want it to just, yk, detect it for you. main character energy.include_typesβ which snapshot types you're letting in the group chat:"single","pre","post".exclude_cleanupβ cleanup algorithms to skip:"number","timeline","empty-pre-post".min_ageβ the minimum snapshot age before it gets backed up (like"30m","1h","1d"). no one likes a backup that's Too Fresh π
π¦ SNAPSHOT TYPES π¦
singleβ standalone snapshots, made by hand or by timeline (hourly snapshots are the classic example). living on their own, thriving.preβ snapshots taken before your package manager does its thing (zypper,dnf, etc.). the "before" pic.postβ snapshots taken after your package manager does its thing. the glow-up pic.
π EXAMPLES π
Detect Snapper configurations:
btrfs-backup-ng snapper detect
List all snapshots for root config:
btrfs-backup-ng snapper list --config root
List only timeline snapshots:
btrfs-backup-ng snapper list --type single
Backup root config to local drive:
sudo btrfs-backup-ng snapper backup root /mnt/backup/root
Backup to remote server with compression:
sudo btrfs-backup-ng snapper backup root ssh://backup@server:/backups/root
Backup specific snapshot:
sudo btrfs-backup-ng snapper backup root /mnt/backup/root --snapshot 559
Backup only timeline snapshots older than 1 hour:
sudo btrfs-backup-ng snapper backup root /mnt/backup --type single --min-age 1h
Dry run to see what would be backed up:
sudo btrfs-backup-ng snapper backup root /mnt/backup --dry-run
List backups at a location:
btrfs-backup-ng snapper restore --list /mnt/backup/root
Restore a specific snapshot:
sudo btrfs-backup-ng snapper restore /mnt/backup/root --snapshot 559 root
Restore all backups:
sudo btrfs-backup-ng snapper restore /mnt/backup/root --all root
Check backup status:
btrfs-backup-ng snapper status --target /mnt/backup/root
Generate config for root:
btrfs-backup-ng snapper generate-config root --target ssh://server:/backups
Generate and save config:
btrfs-backup-ng snapper generate-config root --target /mnt/backup -o snapper.toml
Append to existing config:
btrfs-backup-ng snapper generate-config root --append ~/.config/btrfs-backup-ng/config.toml
π₯ INCREMENTAL TRANSFERS π₯
both backup and restore use incremental btrfs send/receive whenever they possibly can. and the parent? it's whatever the DESTINATION already holds β decided by identity (received_uuid). so a backup finds its parent among the target's slots, and a restore finds its parent among the local config's:
Snapshot 559: 2.1 GB (full, no parent available)
Snapshot 560: 156 MB (incremental from 559)
Snapshot 561: 89 MB (incremental from 560)
likeβ¦ the way that 561 is 89 MB?? that's the incremental slay, we love to see it π
β EXIT STATUS β
0β Success π«Ά1β Failure (Snapper not found, config not found, transfer error, etc.) π
π FILES π
/etc/snapper/configs/β Snapper configuration files/.snapshots/β default snapshot directory for the root config/home/.snapshots/β default snapshot directory for the home config.snapshots/{num}/info.xmlβ the Snapper metadata file for each snapshot.snapshots/{num}/snapshot/β the actual btrfs snapshot subvolume
π SEE ALSO π
btrfs-backup-ng(1), btrfs-backup-ng-restore(1), snapper(8), btrfs-send(8), btrfs-receive(8)
go read these too bestie, iykyk π
π§ NOTES π§
Snapper has to be installed and configured on the source system. the backup destination? literally any btrfs filesystem will do β Snapper is NOT required over there. so chill.
Restored snapshots get assigned the next free snapshot numbers of the local config. and the info.xml is the backup's own, with only the number changed β so type, description, date, cleanup, userdata and any element Snapper wrote are all preserved verbatim. no detail lost, no cap. π
and that's the whole page, bestie!! this was btrfs-backup-ng, January 2026, page BTRFS-BACKUP-NG-SNAPPER(1) π go make some backups, you absolute icon π
π¦ where this page comes from
- fedora 43: btrfs-backup-ng 0.9.20-2.fc43 Β· MIT
- fedora 44: btrfs-backup-ng 0.9.20-1.fc44 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms