The backup job ran every night for a year. Green checkmarks in the log, no errors, everyone comfortable. Then a disk failed, someone reached for the backup, and the restore produced an empty directory. The job had been copying the wrong path the whole time, and nobody had ever tried to restore from it. The data was gone, and the backup that was supposed to save it had never actually held anything.
That story is common, and it points at the real lesson of this part. Making copies is easy. Making copies you can actually restore from, efficiently and on a schedule, is the skill. The main tool for it is rsync, joined by tar for archives, and the discipline around them matters as much as the commands.
New to backups? Practice every command with --dry-run first so nothing moves until you mean it. Running real servers already? Skip to the trailing slash section and the incremental snapshot trick, which save space and prevent the classic accidents. This uses the SSH from Part 13 and the schedule from Part 15.
Use tar to bundle files into a single archive you can ship or store, and rsync to copy or mirror a directory, locally or to another machine over SSH, transferring only what changed. Always run rsync with --dry-run first, mind the trailing slash on the source, and treat --delete as sharp. Follow the 3-2-1 rule for where copies live, schedule the job with cron, and, above everything, test a restore. A backup you have never restored from is a guess, not a backup.
tar bundles, rsync mirrors
Two tools cover most backup work, and they do different jobs. tar rolls a directory tree into one archive file, optionally compressed, which is ideal for a snapshot you want to store or send as a single object. rsync copies a directory to another location and, the part that matters, only moves the parts that changed since last time, which makes repeated backups fast and cheap.
# tar: make one compressed archive, then extract it
$ tar -czf etc-backup.tar.gz /etc
$ tar -xzf etc-backup.tar.gz -C /restore
# rsync: mirror a directory locally, only copying changes
$ rsync -av /var/www/ /backup/www/
sent 4,210 bytes received 38 bytes 8,496.00 bytes/sec
The -a flag is the one you will use most. It means archive mode, a bundle of options that copies recursively and preserves permissions, timestamps, ownership, and symbolic links, so the copy is a faithful match of the original rather than a flattened pile of files. Add -v for a running list, -z to compress over a slow network link, and --progress to watch a big transfer.
| rsync flag | What it does |
|---|---|
-a | Archive mode: recursive, keep perms, times, links |
-v --progress | Show files and transfer progress |
-z | Compress data over the network |
--dry-run | Show what would happen, change nothing |
--delete | Remove files in the target that are gone from the source |
Copy to another machine over SSH
rsync becomes a real backup tool the moment the destination is another server. Point it at a remote path and it runs over SSH, using the keys you set up earlier, so an offsite copy is one command. Because it only sends the changed blocks, the nightly run after the first is quick even for large trees.
# push a local directory to a backup server over SSH
$ rsync -avz /home/ backup@nas.internal:/backups/home/
# always preview a mirror with --delete before running it
$ rsync -avz --delete --dry-run /home/ backup@nas.internal:/backups/home/
... (list of what would be sent and deleted)
$ rsync -avz --delete /home/ backup@nas.internal:/backups/home/
The --delete flag turns rsync from a copy into a true mirror: files removed from the source are removed from the backup too. That is exactly what you want for a mirror and exactly what wrecks a backup if the source path is wrong, because rsync will happily empty the destination to match an empty or mistyped source. The --dry-run before it is not optional, it is the seatbelt.
rsync treats a source with a trailing slash differently from one without, and this single character causes more confusion than any flag. rsync -a src/ dest copies the contents of src into dest. rsync -a src dest copies the folder src itself into dest, giving you dest/src. Same words, different result.
Get it wrong with --delete in the mix and you either nest a folder one level too deep or wipe files that did not belong to the set. The habit that saves you: decide whether you mean the folder or its contents, add or drop the trailing slash to match, and confirm with --dry-run. The destination trailing slash does not matter; the source one is everything.
Space-smart snapshots with hard links
A single mirror only ever holds the latest state, so if a file was corrupted three days ago and copied over your good version, the mirror has the bad one too. The fix is keeping several dated snapshots, but storing a full copy every day wastes enormous space. rsync solves this with --link-dest, which compares against yesterday snapshot and hard links every unchanged file instead of copying it. Each snapshot looks complete, yet unchanged files exist on disk only once.
# today snapshot, hard-linking anything unchanged since yesterday
$ rsync -a --delete
--link-dest=/backups/2026-07-03
/home/ /backups/2026-07-04/
$ du -sh /backups/2026-07-04 # only the changed files cost space
82M /backups/2026-07-04
The result is a row of daily folders, each browsable as a full backup, that together take barely more room than one copy plus the changes. Delete an old dated folder and only the files unique to it are freed, because the rest are still linked by newer snapshots. This is the idea behind time-machine style backups, in three lines of rsync.
Put it on a schedule
A backup you have to remember to run is a backup that will not run. Wrap the rsync in a small script, redirect its output to a log, and let cron fire it nightly, exactly as covered in the scheduling part. Then set a calendar reminder, once a quarter, to actually restore a file from it.
# crontab -e, run the backup script at 01:30 every night
30 1 * * * /usr/local/bin/nightly-backup.sh >> /var/log/backup.log 2>&1
| Use | Reach for |
|---|---|
| One archive to store or ship | tar |
| Repeated copy, only the changes | rsync |
| Offsite copy over the network | rsync over SSH |
| Dated history without wasting space | rsync with –link-dest |
A real opinion: an untested backup is not a backup
Most backup advice stops at making the copy. That is the easy half and the half that lulls people into the disaster in the opening. The copy running is not proof of anything; the only proof is a successful restore. My firm position is that a backup you have never restored from does not exist, and you should assume it is broken until a test says otherwise. Schedule a real restore of a sample file on a recurring basis and treat a failed restore as the emergency it is, not the copy job going green.
The second half of the opinion is to prefer rsync over scp for anything you do more than once. scp copies everything every time; rsync copies the differences, resumes a broken transfer, and can mirror and snapshot. For a one off grab, scp is fine. For a backup, a sync, or any repeated job, rsync is the right default and it is already installed.
Practice the whole safe pattern on throwaway folders: preview, then run, then prove the trailing slash. Nothing here can hurt real data.
mkdir -p /tmp/src/sub && touch /tmp/src/a /tmp/src/sub/b
rsync -av --dry-run /tmp/src/ /tmp/dest/ # preview
rsync -av /tmp/src/ /tmp/dest/ # contents of src
rsync -av /tmp/src /tmp/dest2/ # the src folder itself
ls /tmp/dest /tmp/dest2
Compare the two destinations and the trailing slash difference becomes something you never forget.
How would you back up /home to another server every night, keeping a few days of history without wasting disk?
rsync over SSH to the backup server, run from cron nightly, using --link-dest pointed at the previous day so unchanged files are hard linked rather than copied. That gives dated, browsable snapshots that together cost roughly one full copy plus daily changes. Strong answers add --dry-run discipline, a log redirect, and, the part that impresses, a scheduled restore test to prove the backup works. Mentioning the trailing slash and --delete care shows real rsync experience.
Questions you ask after a scare
Is a RAID array a backup? No. RAID protects against a disk failing, but it faithfully copies a deletion, a corruption, or a ransomware encryption to every disk at once. It is availability, not backup. You still need separate copies you can restore from a point in time.
tar or rsync, which should I use? tar when you want one archive file to store or move, such as a snapshot of a config directory. rsync when you are copying or mirroring a tree repeatedly and want only the changes to move. Many setups use both, tar for archives and rsync to ship them.
Does rsync copy permissions and ownership? With -a, yes, it preserves permissions, timestamps, and symlinks, and ownership too when you run it with enough privilege on both ends. That is why archive mode is the sensible default for backups.
How do I stop a big rsync from saturating the network? Add --bwlimit to cap the transfer rate, and -z to compress on slow links. For very large first runs, seed the backup locally, then let the nightly incrementals carry only the changes.
How long should I keep backups? A common pattern keeps several daily copies, a few weekly, and a few monthly, so recent mistakes and older ones are both recoverable. Balance the history against disk space, and against any retention rule your organization has to follow. Hard-linked snapshots make a longer history cheap.
Can I just rsync a live database? No, and this catches people. Copying the files of a running database can capture a half-written, torn state that will not restore. Use the database dump tool, such as mysqldump or pg_dump, to write a consistent export to a file, and back up that file. Snapshot the data directory only when the database is stopped or quiesced. The dump is also easier to restore into a fresh server than a pile of raw data files, so it doubles as a portable copy.
Where should the offsite copy go? Anywhere failures do not correlate with your main site: another building, a remote server, or object storage in the cloud. The point of the offsite copy in 3-2-1 is surviving a fire, flood, or theft that takes the whole room.
Your data now has copies you can actually restore, made efficiently and on a schedule. The next question is the disk those copies and everything else live on, and how to grow it without downtime. That is LVM, the logical volume layer that lets you add space to a full filesystem while it stays in use. Work the series in order from the Complete Guide.


DrJha