LinuxCommandLibrary
GitHubF-DroidGoogle Play Store

Backup & Imaging

Backup Strategy

A good backup follows the 3-2-1 rule: keep 3 copies of your data, on 2 different kinds of media, with 1 copy stored offsite. The tool you reach for depends on what you are protecting.
GoalReach for
Sync files to another disk
Versioned, deduplicated backups
Clone a whole disk or partition
Rescue a failing drive
Push to cloud storage
Snapshot a live filesystem
$ lvmbtrfszfs
copy
Test your restores regularly - a backup you have never restored is only a hope.

File Backups with rsync

`rsync` copies only the differences between source and destination, which makes repeat backups fast. The `-a` (archive) flag preserves permissions, timestamps, symlinks, and ownership.
$ rsync -a /home/user/ /mnt/backup/user/
copy
$ rsync -ah --info=progress2 /data/ /mnt/backup/data/
copy
Add `--delete` to mirror the source exactly, removing files from the destination that no longer exist in the source.
$ rsync -a --delete /data/ /mnt/backup/data/
copy
A trailing slash on the source matters: `src/` copies the contents of src, while `src` copies the directory src itself.
FlagDescription
-aArchive mode (preserve metadata, recurse)
-vVerbose output
-zCompress data during transfer
-hHuman-readable sizes
--deleteRemove extra files from destination
-n / --dry-runShow what would happen, change nothing
--excludeSkip matching paths
--progressShow per-file progress
Always dry-run first: when using `--delete`, do a `--dry-run` so you can confirm nothing important will be wiped.

Backups over SSH

When either side of an `rsync` is `user@host:path`, the transfer runs over SSH automatically, still copying only changes. Add `-z` to compress on slow links.
$ rsync -avz /data/ user@host:/backup/data/
copy
$ rsync -avz user@host:/var/www/ /mnt/backup/www/
copy
Pass SSH options, such as a non-standard port, through `-e`.
$ rsync -avz -e "ssh -p 2222" /data/ user@host:/backup/data/
copy
For a quick one-off copy of a single file, `scp` is simpler.
$ scp backup.tar.gz user@host:/backup/
copy

Incremental Snapshots

With `--link-dest`, `rsync` hard-links unchanged files to a previous backup, so each snapshot looks complete but only uses extra space for files that changed.
$ rsync -a --delete --link-dest=/backup/prev /data/ /backup/2026-06-06/
copy
This gives you browseable, dated snapshots at the storage cost of an incremental backup. Rotate by pointing each new run at the previous day's directory. rsnapshot automates exactly this scheme with a config file and retention levels.

Archiving Backups

A `tar` archive bundles many files into one, ideal for a point-in-time snapshot. Combine with compression to save space.
$ tar czf backup-$(date +%F).tar.gz /home/user
copy
$ tar xzf backup-2026-06-06.tar.gz
copy
For large datasets, `zstd` compresses much faster than gzip at similar or better ratios.
$ tar --zstd -cf backup.tar.zst /data
copy
`tar` supports incremental archives: `-g` keeps a snapshot file that records what changed between runs. The first run is a full backup; later runs with the same snapshot file only store changes.
$ tar czf full.tar.gz -g backup.snar /data
copy
$ tar czf incr1.tar.gz -g backup.snar /data
copy
To restore, extract the full archive first, then each incremental in order.Stream an archive straight to a remote host without a temporary file.
$ tar czf - /data | ssh user@host "cat > /backup/data.tar.gz"
copy
See the Compression & Archiving basics page for the full set of `tar`, `gzip`, `xz`, and `zstd` options.

Snapshot & Dedup Tools

Dedicated backup programs add deduplication, encryption, compression, and retention policies on top of plain copies. They store each file's blocks once, so re-running a backup is cheap.
ToolStrengths
borgDedup, compression, encryption, mountable archives
resticSimple, fast, many cloud backends built in
duplicityEncrypted incremental backups via GPG
bupGit-based dedup, handles huge files well
rsnapshotrsync plus hard-link rotation, no extra format
Initialize a `borg` repository, then create a compressed, deduplicated archive.
$ borg init --encryption=repokey /mnt/backup/repo
copy
$ borg create --compression zstd /mnt/backup/repo::{now} /home/user
copy
`restic` works the same way and speaks to local disks, SFTP, S3, and more.
$ restic -r /mnt/backup/repo init
copy
$ restic -r /mnt/backup/repo backup /home/user
copy
Prune old snapshots with a retention policy so backups do not grow forever. With `borg`, run `compact` afterwards to actually free the space.
$ borg prune --keep-daily=7 --keep-weekly=4 /mnt/backup/repo
copy
$ borg compact /mnt/backup/repo
copy
$ restic -r /mnt/backup/repo forget --keep-daily 7 --keep-weekly 4 --prune
copy
Test a restore by extracting a snapshot to a scratch directory, or mount the repository and browse it.
$ restic -r /mnt/backup/repo restore latest --target /tmp/restore-test
copy
$ borg mount /mnt/backup/repo /mnt/restore
copy
If the repository is encrypted, the backup is only as safe as the key and passphrase. Export the key and store it somewhere that is not inside the backup.

Databases & Live Data

Copying a running database's files mid-write produces a corrupt backup. Dump to a consistent snapshot first, then back up the dump like any other file.
$ mysqldump --all-databases > mysql-backup.sql
copy
$ pg_dumpall > postgres-backup.sql
copy
$ sqlite3 app.db ".backup app-backup.db"
copy
The same applies to anything that writes constantly (virtual machine disks, mail spools): stop the writer, dump it, or back up from a filesystem snapshot (see below).

Disk & Partition Imaging

`dd` copies data block by block, making an exact image of a disk or partition. Identify the target device first with `lsblk` and double-check it.
$ dd if=/dev/sda of=/dev/sdb bs=4M status=progress
copy
Save a partition to a compressed image file instead of another disk.
$ dd if=/dev/sda1 bs=4M status=progress | gzip > sda1.img.gz
copy
Restore an image back onto a device.
$ gunzip -c sda1.img.gz | dd of=/dev/sda1 bs=4M status=progress
copy
Careful: `dd` writes wherever you point it with no confirmation. A wrong `of=` value will destroy data instantly. Check the device name twice, then once more. Image only unmounted partitions: an image of a filesystem that is changing underneath you is inconsistent.
OptionDescription
if=Input file or device
of=Output file or device
bs=Block size (4M is a good default)
status=progressShow transfer progress
conv=noerror,syncKeep going past read errors, pad blocks
conv=fsyncFlush to the device before exiting
count=Copy only N blocks

Writing Images to USB

To write an installer ISO to a USB stick, `dd` it to the whole device (not a partition). `conv=fsync` makes sure everything is flushed before the command returns.
$ dd if=distro.iso of=/dev/sdc bs=4M status=progress conv=fsync
copy
Plain `cp` and `cat` can also stream an image to a device.
$ cp distro.iso /dev/sdc && sync
copy
Wipe old filesystem signatures from a device before reusing it.
$ wipefs -a /dev/sdc
copy

Resilient Imaging & Recovery

When a drive is failing, use `ddrescue` instead of `dd`: it retries bad sectors, works from the easy areas first, and keeps a map file so it can resume later.
$ ddrescue /dev/sda rescue.img rescue.map
copy
$ ddrescue -r3 /dev/sda rescue.img rescue.map
copy
`partclone` images only the used blocks of a filesystem, so it is faster and smaller than a full `dd` of an empty-ish partition. Use `-c` to create an image and `-r` to restore it.
$ partclone.ext4 -c -s /dev/sda1 -o sda1.img
copy
$ partclone.ext4 -r -s sda1.img -o /dev/sda1
copy
`clonezilla` wraps these tools into a guided disk-cloning environment for bare-metal backups.For repairing a system that no longer boots, recovering deleted files with `testdisk` and `photorec`, and reading SMART health, see the System Recovery basics page.

Filesystem-level Snapshots

Modern filesystems and volume managers can snapshot a live system instantly, giving you a stable, consistent view to back up from.
SystemCreate a snapshot
LVMlvcreate -s -n snap -L 5G /dev/vg/lv
Btrfsbtrfs subvolume snapshot / /snap
ZFSzfs snapshot pool/data@backup
Create an LVM snapshot, mount it read-only, and back it up while the system keeps running. Remove the snapshot when done so it stops consuming space.
$ lvcreate -s -n root_snap -L 5G /dev/vg0/root
copy
$ mount -o ro /dev/vg0/root_snap /mnt/snap
copy
$ rsync -a /mnt/snap/ /mnt/backup/root/
copy
$ umount /mnt/snap && lvremove /dev/vg0/root_snap
copy
Btrfs and ZFS snapshots are even cheaper, create them read-only (`-r`) so the backup source cannot change.
$ btrfs subvolume snapshot -r / /.snapshots/2026-06-06
copy
$ zfs snapshot tank/home@2026-06-06
copy
`snapper` and `timeshift` automate scheduled Btrfs/LVM snapshots with retention.
$ snapper create --description "before upgrade"
copy
$ timeshift --create
copy
Snapshots live on the same disk and are not a backup by themselves. Copy them somewhere else.

Cloud & Remote Sync

`rclone` syncs files to dozens of cloud providers (S3, Backblaze, Google Drive, and more) after a one-time `rclone config`.
$ rclone copy /data remote:backup/data
copy
$ rclone sync /data remote:backup/data --progress
copy
Check what would change without transferring, verify a finished backup, or mount a remote as a local folder.
$ rclone sync /data remote:backup --dry-run
copy
$ rclone check /data remote:backup/data
copy
$ rclone mount remote:backup /mnt/remote
copy
Careful: like `rsync --delete`, `rclone sync` makes the destination match the source, including deletions. Use `copy` when you only want to add files.

Verify & Automate

A backup is only good if it is intact. Record checksums when you make a backup, then verify them on restore.
$ sha256sum backup.tar.gz > backup.sha256
copy
$ sha256sum -c backup.sha256
copy
Schedule backups so they actually happen. Edit your crontab and add a nightly job.
$ crontab -e
copy
$ 0 2 * * * rsync -a --delete /data/ /mnt/backup/data/
copy
Automate the backup, but verify restores by hand on a schedule. The only proven backup is one you have successfully restored.
Copied to clipboard
Kai