Using tar and rsync Precisely
In one line
tar is a tool that captures a point in time, and rsync is a tool that brings a state into line. In backup design the two are not competitors but a division of roles.
Why this was needed
"Should I back up with tar or rsync?" has no fixed answer. If you need archives per generation, use tar; if you need a copy of the latest state, use rsync. And most real-world setups use both.
How it works
tar
tar -czf /backup/etc-$(date +%F).tar.gz --acls --xattrs --selinux --numeric-owner -C / etc
tar -tzf /backup/etc-2026-08-20.tar.gz | head
tar -xzf /backup/etc-2026-08-20.tar.gz -C /restore/
The precise meaning of the options.
-c(create),-x(extract),-t(list), and-f(file) are the basic combination.- Compression is
-z(gzip),-j(bzip2),-J(xz), and--zstd. -Cchanges directory before doing the work. Always use it so that absolute paths do not go into the archive.tar -czf x.tgz /etcputs/etc/...inside the archive and takes away your choice of path on restore.-p(preserve permissions) and--numeric-ownerrestore permissions and owners exactly.--acls,--xattrs, and--selinuxinclude ACLs, extended attributes, and the SELinux context, respectively. On a system that uses SELinux, restoring without these options leaves the service unable to start.--one-file-systemdoes not cross into other filesystems. It prevents the accident of mounted network storage being pulled in.--listed-incremental=<스냅샷파일>manages incremental backups (the placeholder is the snapshot file path). The snapshot file holds the state, so that file must be kept along with the archives.--strip-components=Nremoves leading path elements on restore.
Always check the path on restore. Extracting directly with -C / overwrites the current system configuration. The safe procedure is to extract to a temporary path, inspect the contents, and then move over only the files you need.
mkdir -p /restore/etc-check
tar -xzf /backup/etc-2026-08-20.tar.gz -C /restore/etc-check
diff -r /restore/etc-check/etc/nginx /etc/nginx | head -40
GNU tar and BSD tar (bsdtar) differ in option handling and some behavior. A typical problem is that extracting an archive made on macOS on Linux also produces files related to extended attributes. Backup scripts must be verified on the actual production distribution.
rsync
rsync -aHAX --numeric-ids --delete --dry-run /srv/data/ backup@10.0.9.2:/backup/prod/data/
-ais the same as-rlptgoD. ACLs (-A), extended attributes (-X), and hard links (-H) are not included.--numeric-idsuses numeric UID/GID instead of names. It prevents owners from being mapped incorrectly when restoring to a different system.-i(itemize) shows, one line at a time, what change is taking place. Using it together with-nshould become a habit.--bwlimitandionice -c 3 nice -n 19lower the load on production.
Generation backups are made cheaply with hard links.
rsync -aHAX --numeric-ids --delete --link-dest=/backup/prod/daily.1 /srv/data/ /backup/prod/daily.0/
Each generation looks like a full snapshot, but the disk is occupied only by the changes.
Division of roles between the two tools
| Need | Tool |
|---|---|
| A single archive file for a specific point in time | tar |
| A single object to move off-site | tar (+ compression, encryption) |
| Keeping a copy of the latest state | rsync |
| Cheap per-generation snapshots | rsync --link-dest |
| Remote sync that saves bandwidth | rsync (delta transfer) |
What you see in the field
The --delete accident. If it runs while the source is empty or the mount has come undone, it deletes all the data on the target. This is an accident that genuinely keeps recurring in practice. A guard is essential.
The accident where a generation backup is copied with a tool that does not know about hard links and the size triples. -H is not included in -a.
So nothing goes out of step in transit
tar and rsync look simple, but there are places where they silently go out of step when moving large volumes.
Capturing files as they change breaks them. If a file changes while it is being read, tar prints the
file changed as we read it warning and moves on with only that file broken.
If you cannot stop the service, take a snapshot (LVM, filesystem, cloud volume) and capture that
instead.
Preserve hard links and sparse files. If you transfer without options, each hard link becomes a separate copy and the size multiplies, and sparse files are filled with zeros and blow up.
tar --numeric-owner --acls --xattrs --sparse -cf - /srv | zstd -T0 > srv.tar.zst
rsync -aHAX --sparse --numeric-ids /srv/ backup:/srv/
-a alone does not carry over hard links (H), ACLs (A), or extended attributes (X). SELinux
labels are contained in -X.
Make it resumable when it is cut off midway. With --partial --append-verify, a restart does not
fetch everything from the beginning. It makes a big difference when moving one large file over several days.
A trailing slash makes a difference. rsync -a /src/ /dst/ transfers the contents,
and rsync -a /src /dst/ creates /dst/src. Accidents in which this single character makes the
path one level deeper keep recurring in scripts.
Look with your own eyes before deleting. --delete removes whatever exists only on the destination.
If the source path is wrong, it empties the destination entirely.
rsync -aHAX --delete --dry-run --itemize-changes /src/ /dst/ | head -50
Verification is a separate step. rsync uses checksums during the transfer, but it does not tell you whether a file has gone bad later. If you keep a list together with hashes, you can check even months later.
find /srv -type f -print0 | sort -z | xargs -0 sha256sum > manifest.sha256
sha256sum -c manifest.sha256 --quiet
What you will do in the next labs
With tar you handle full and incremental backups, exclusions, and splitting, and with rsync you handle dry-run, guards, generation backups, and load control. In both labs, you verify the result at the end.