Btrfs snapshots make rollback fast, but a snapshot on the same filesystem can disappear with device failure, filesystem loss, host loss, or administrative compromise. A sound backup design creates read-only snapshots, moves them to another fault domain with btrfs send/receive, protects the incremental chain, and regularly proves restoration.
This guide follows the official documentation for subvolumes and snapshots, btrfs send, and btrfs receive. Check the running kernel and btrfs-progs versions before adopting newer options.
1. A fast snapshot is not yet a backup
| Mechanism | Good protection against | Does not inherently protect against |
|---|---|---|
| Local snapshot | Accidental deletion, bad updates, rapid rollback | Device or filesystem loss, stolen host, same-admin compromise |
| RAID or replica | Some device failures and availability loss | Replicated deletion, ransomware, logical corruption |
| Send/receive to an independent system | Source loss and point-in-time recovery | Poor retention, untested restores, or shared compromised credentials |
Copy-on-write lets a snapshot share unchanged extents with its source, so creation is fast and initial space use is small. Sharing storage is exactly why a local snapshot does not replace an independent copy. Define the goal through RPO, RTO, fault domains, and retention rather than merely stating that snapshots exist.
2. Understand subvolumes before scheduling
A subvolume is a separate file tree inside Btrfs, not a block device like an LVM logical volume. A snapshot is a new subvolume sharing CoW data at creation. The easily missed rule is that snapshots are not recursive: a nested subvolume becomes an empty stub in the parent snapshot.
btrfs subvolume list /srv
btrfs subvolume show /srv/app
findmnt -t btrfs
Inventory every subvolume, mount point, and owning application. If /srv/app/database is its own subvolume inside /srv/app, snapshotting /srv/app does not include database contents. Snapshot and send each required subvolume under a controlled manifest.
3. Filesystem-consistent is not always application-consistent
A snapshot captures a filesystem-consistent state, while application data may remain in memory or a transaction may span files. Databases, VM images, and brokers need application-aware handling:
- Run a pre-hook to flush, checkpoint, or enter backup mode.
- Pause writes for the shortest necessary window.
- Create the read-only snapshot.
- Run the post-hook and resume service.
- Send the snapshot asynchronously afterward.
fsfreeze is one tool, not a substitute for database backup guidance. Never keep a filesystem frozen during a multi-hour transfer. For dependent subvolumes, build an application-level consistency group or explicitly document the non-atomic recovery point.
4. Create immutable, clearly named snapshots
install -d -m 0700 /srv/.snapshots/app
btrfs subvolume snapshot -r \
/srv/app \
/srv/.snapshots/app/app-2026-10-16T110000+0700
btrfs property get \
/srv/.snapshots/app/app-2026-10-16T110000+0700 ro
btrfs subvolume show \
/srv/.snapshots/app/app-2026-10-16T110000+0700
btrfs send requires involved snapshots to have the actual read-only flag; a read-only mount is insufficient because another writable mount may exist. Record UUID, parent UUID, generation, time, application checkpoint, and job state in a catalog. Human-readable names help operations but cannot prove ancestry.
5. Establish the first full send
This example writes a temporary stream so exit status and checksum can be checked explicitly before transport. Staging needs sufficient space and protection because a send stream is not encrypted by default.
umask 077
btrfs send \
-f /var/tmp/app-2026-10-16.full.btrfs \
/srv/.snapshots/app/app-2026-10-16T110000+0700
sha256sum /var/tmp/app-2026-10-16.full.btrfs \
> /var/tmp/app-2026-10-16.full.btrfs.sha256
Move the stream and checksum through an authenticated encrypted channel. At the destination, verify and receive into a dedicated Btrfs filesystem:
sha256sum -c app-2026-10-16.full.btrfs.sha256
install -d -m 0700 /backup/received/app
btrfs receive -f app-2026-10-16.full.btrfs \
/backup/received/app
Mark the job successful only after send, transport, checksum, and receive all succeed. Expire staging files deliberately so they cannot silently fill the source filesystem.
6. Incremental send is a parent contract
After the full base, send only changes relative to a parent that exists identically at both ends:
btrfs subvolume snapshot -r \
/srv/app \
/srv/.snapshots/app/app-2026-10-17T110000+0700
btrfs send \
-p /srv/.snapshots/app/app-2026-10-16T110000+0700 \
-f /var/tmp/app-2026-10-17.incremental.btrfs \
/srv/.snapshots/app/app-2026-10-17T110000+0700
The parent must remain unmodified and correspond to its received copy. Do not turn a received base read-write, patch files inside it, or delete the parent before the next incremental is complete. Btrfs documentation warns that changing a received snapshot's read-only state can break assumptions associated with received_uuid.
7. Retention must not break the chain
A policy may retain 7 daily, 5 weekly, and 12 monthly points, but deletion order is the risky part. Each job must identify the next parent that is present and valid at source and destination. Only after the child is received, verified, and promoted as the next base can the old parent become eligible for deletion.
- Keep source and destination retention independent; destination commonly retains more.
- Create periodic new full bases to bound historical dependency and recovery time.
- If the parent is lost, establish a new full base instead of forcing an incremental.
- Lock send and retention jobs so they cannot race.
- Measure exclusive and referenced space; snapshot count is not actual capacity use.
8. Protect the receiver and transport
Official documentation notes that btrfs receive does not fully validate whether an incremental stream makes sense; a crafted stream may create reflinks to arbitrary files in the same filesystem. Therefore:
- never receive streams from untrusted sources;
- authenticate and encrypt streams over untrusted networks;
- receive into a dedicated filesystem and path without unrelated sensitive data;
- deny user writes to the receiving path while receive is running;
- separate backup credentials from source administration and restrict destination commands;
- consider immutable or offline copies to limit ransomware blast radius.
Send-stream checksums detect corruption in commands; they do not provide confidentiality or sender authentication. Transport encryption, storage encryption, key management, and access logging remain separate controls.
9. Scrub, SMART, and backup solve different problems
btrfs scrub reads data and metadata, verifies checksums, and may repair from a good redundant copy. It detects silent corruption but cannot restore a file that was logically deleted. SMART highlights some hardware symptoms; RAID sustains service through certain disk faults; send/receive creates recovery points. Production needs these complementary layers.
10. Monitor recoverability
| Signal | Alert condition |
|---|---|
| Age of latest successful snapshot | Exceeds RPO |
| Full/incremental send and receive | Nonzero exit, timeout, or missing completion |
| Parent UUID and catalog | Mismatch or missing endpoint copy |
| Bytes and duration | Unexpected departure from baseline |
| Source, staging, and destination capacity | Insufficient for the next point |
| Age of last restore test | Exceeds exercise schedule |
A green dashboard based only on the last command's exit status is weak evidence. The catalog should connect source snapshot, received snapshot, checksum, application checkpoint, and restore-test result.
11. Run an end-to-end restore drill
- Select a random recovery point from the catalog.
- Restore to an isolated host and filesystem, never over production.
- When writes are needed, create a read-write snapshot from the read-only received base.
- Inspect ownership, modes, xattrs, ACLs, symlinks, and application data.
- Run logical checks: database recovery, business checksums, sample files, and service startup.
- Measure RTO, record manual steps, improve the runbook, and securely retire test data.
btrfs subvolume snapshot \
/backup/received/app/app-2026-10-17T110000+0700 \
/restore-test/app-writable
Do not call a backup verified because snapshots can be listed. Evidence is a clean restoration, application-readable data, and completion inside the RTO.
Production checklist
- The inventory covers every nested subvolume; nobody assumes recursive snapshots.
- Pre- and post-hooks create an application-consistent recovery point.
- Send snapshots stay read-only and UUID/generation metadata is cataloged.
- The copy uses another fault domain, credential set, and retention policy.
- Streams come only from trusted sources, are protected in transit, and use an isolated receive path.
- Retention never deletes the parent needed by the next incremental.
- Capacity, age, duration, bytes, checksums, and receive results have alerts.
- New full bases are scheduled and missing-parent recovery is documented.
- Scrub and hardware monitoring run separately and are not mistaken for backup.
- Recurring restore drills prove both RPO and RTO.
Conclusion
Btrfs makes snapshots and incremental replication efficient, but reliability comes from the surrounding system: know subvolume boundaries, quiesce applications, preserve immutable snapshots, transfer to an independent fault domain, protect the receiver, manage parents, and rehearse restoration. A snapshot accelerates rollback; only a successfully restored copy proves that a backup exists.




No comments yet. Be the first to share your thoughts.