The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Copy directory contentsrsync -a /srv/app/ /backup/app/View examples
Copy directory by namersync -a /srv/app /backup/View examples
Preserve ACLs and xattrssudo rsync -aAX /srv/app/ /backup/app/View examples
Stay on one filesystemrsync -a --one-file-system /srv/ /backup/srv/View examples
Preview itemized changesrsync -ain /srv/app/ /backup/app/View examples
Read exclude patternsrsync -a --exclude-from=/etc/backup/app.exclude \ /srv/app/ /backup/app/View examples
Mirror with delayed deletionrsync -ain --delete-delay --max-delete=100 /srv/app/ \ /backup/app/View examples
Retain replaced destination filesrsync -a --backup --backup-dir=../changed /srv/app/ \ /backup/current/View examples
Push through SSHrsync -a -e 'ssh -o BatchMode=yes' /srv/app/ \ backup@store.example:/vault/app/View examples
Protect remote argumentsrsync -a -s ./data/ \ backup@store.example:'/vault/team data/'View examples
Bound idle network timersync -a --timeout=120 --partial-dir=.rsync-partial \ /srv/app/ backup@store.example:/vault/app/View examples
Build a hard-linked snapshotrsync -a --link-dest=../previous /srv/app/ \ /backup/snapshots/2026-08-12/View examples
Audit snapshot changesrsync -ain --link-dest=../previous /srv/app/ \ /backup/snapshots/next/View examples
Checksum-compare a restorersync -nric --delete /backup/restore-test/ \ /srv/restore-reference/View examples
Preview a restorersync -ain /backup/snapshots/2026-08-12/ \ /srv/restore-test/View examples
Inspect local rsync versionrsync --versionView examples
Print transfer statisticsrsync -a --stats /srv/app/ /backup/app/View examples

rsync efficiently reconciles directory trees locally or across a remote shell, but synchronization alone is not backup history. First make path semantics and deletion policy observable with a dry run; then preserve independent generations, validate exit status, protect credentials, monitor last success, and practice restores. For databases and other live state, feed rsync an application-consistent dump or filesystem snapshot instead of assuming a directory scan is one point in time.

Step by step

Detailed examples

01

Resolve source and destination paths before transferring

A trailing slash on a directory source means its contents; without the slash, the directory name becomes another destination level. This tiny difference can create a plausible but wrong restore tree. Ensure the destination directory exists when its interpretation matters, use absolute paths in automation, and preview with -n and -i. Archive mode preserves a useful Unix metadata set and symlinks, but it does not itself create historical generations or make a live source consistent.

Compare the two directory layouts safely
rsync -ain /srv/app/ /backup/app/
rsync -ain /srv/app /backup/

Note: Both commands are dry runs. Review the destination-relative names before removing -n.

Back to quick reference ↑
02

Choose metadata and filesystem boundaries explicitly

-a expands to recursive copying plus common permissions, ownership, group, times, symlinks, and device or special-file handling; it does not include ACLs, extended attributes, or hard-link topology. Add -A, -X, or -H only when required and supported on both ends. Restoring ownership, devices, security xattrs, or privileged ports can require root and can be dangerous on an untrusted tree. --one-file-system prevents descent into nested mounts but also excludes wanted mounted data, so inventory mount points first. Use --numeric-ids only when numeric identity mapping is intentional across hosts.

Preview a metadata-rich, single-filesystem backup
sudo rsync -aAXHn --one-file-system --numeric-ids /srv/app/ /backup/app/

Note: H can consume substantial memory on large hard-link sets. Verify filesystem ACL and xattr support and the destination trust boundary.

Back to quick reference ↑
03

Make the transfer list reviewable before mutation

Combine --dry-run with --itemize-changes so planned updates are visible. Filter rules operate on transfer-relative paths and rule order matters; an excluded directory may prevent traversal to a later include. Keep filters version-controlled, test representative paths, and remember that exclusions can also protect destination files from deletion unless delete-excluded or side-specific filter modifiers change that behavior. A dry run cannot predict runtime failures or source changes after the file list is built.

Review a policy file and planned transfer
sed -n '1,120p' /etc/backup/app.exclude
rsync -ain --exclude-from=/etc/backup/app.exclude /srv/app/ /backup/app/

Note: Inspect all itemized deletions and type changes, not only transferred byte counts.

Back to quick reference ↑
04

Treat mirroring and deletion as destructive operations

--delete makes the receiver resemble the sender by removing extra destination paths; a reversed source, empty mount, broken include rule, or partial source view can therefore erase useful data. Require a successful source preflight, preview with the exact filter and delete options, cap surprises with --max-delete, and keep a generation outside the mirror. --delete-delay postpones removals until after transfer work, but it does not turn a mirror into a transactional snapshot. --backup-dir can retain replaced and deleted files, provided its location and rotation policy do not collide with the transfer tree.

Preview a bounded mirror policy
test -r /srv/app/.backup-source-marker
mountpoint -q /backup
rsync -ain --delete-delay --max-delete=100 --exclude-from=/etc/backup/app.exclude /srv/app/ /backup/current/

Note: Do not remove -n until the source marker, mounted destination, filter rules, and deletion list are all confirmed.

Back to quick reference ↑
05

Use authenticated transport and fail visibly on outages

The host:path form normally runs rsync through a remote shell such as SSH; direct rsync-daemon transport is not encrypted by itself. Use a dedicated least-privileged remote account, verify host keys, restrict its key or server-side command, and keep passphrases or daemon password files out of crontabs and process arguments. Keep both endpoints patched against current rsync advisories. BatchMode makes missing credentials fail rather than hang. --timeout covers idle I/O, not a total runtime. Preserve partial data only in a private directory, inspect the exit status, retry safely after network loss, and never advance a current-snapshot pointer after a partial transfer. Both endpoints need compatible rsync versions and options.

Preview a bounded SSH transfer
ssh -o BatchMode=yes backup@store.example true
rsync -ain -s --timeout=120 --partial-dir=.rsync-partial -e 'ssh -o BatchMode=yes' /srv/app/ backup@store.example:/vault/app/

Note: This checks connectivity and performs a dry run. A private SSH key is a secret; protect it with filesystem permissions and restrict its server-side authority.

Back to quick reference ↑
06

Create each hard-linked generation in a new directory

--link-dest compares destination-relative files with a prior tree and hard-links files whose content and preserved attributes match, giving each generation a complete namespace without duplicating unchanged file data. The reference path is interpreted relative to the new destination when it is not absolute. Create the destination fresh on the same filesystem as the reference, and publish it only after rsync exits successfully. Never use --inplace against a hard-linked snapshot: modifying a shared inode can corrupt historical generations. Hard links do not cross filesystems, and attribute mapping or mount options can prevent expected linking.

Stage one snapshot generation
snapshot_root=/backup/snapshots
next=$snapshot_root/2026-08-12
previous=$snapshot_root/2026-08-11
test ! -e "$next"
test -d "$previous"
mkdir "$next"
rsync -ain --link-dest=../2026-08-11 /srv/app/ "$next/"

Note: This stages an empty directory and performs only a dry run. A production script should remove or quarantine an incomplete generation and update any current pointer only on exit status 0.

Back to quick reference ↑
07

Back up a consistent source and prove that it restores

rsync scans and transfers over time; files modified during the run can yield a generation that never existed as one application state. Quiesce the application, use its native dump, or rsync from a coherent filesystem or volume snapshot. A successful rsync exit confirms the transfer completed according to its rules, not that the data is semantically valid. Periodically restore a selected generation to an isolated path, verify permissions and application checks, and checksum-compare critical content. Keep at least one offline or separately controlled copy so compromised source credentials cannot delete every generation.

Preview and compare an isolated restore
mkdir -p /srv/restore-test
rsync -ain /backup/snapshots/2026-08-12/ /srv/restore-test/
rsync -nric --delete /backup/snapshots/2026-08-12/ /srv/restore-test/

Note: The commands do not copy because -n is present. Run an authorized restore separately, then repeat the checksum comparison and application-level validation.

Back to quick reference ↑
08

Pin compatible behavior and monitor completed generations

Distributions can ship substantially different rsync releases, and remote transfers negotiate protocol and feature availability between both endpoints. Check both versions before relying on newer options such as protected arguments, algorithms, or daemon restrictions; confirm behavior in the locally installed manuals. Capture --stats, itemized changes, duration, exit status, and the final generation name. Exit codes 23 and 24 indicate partial transfer conditions, while timeout codes identify network failure; decide explicitly whether vanished volatile files are acceptable. Monitor the age and restoreability of the last completed generation, not merely that a scheduler invoked rsync.

Inspect endpoint capabilities without transferring data
rsync --version
ssh -o BatchMode=yes backup@store.example rsync --version
rsync -ain --stats /srv/app/ backup@store.example:/vault/app/

Note: The remote commands require authorized network access but the rsync invocation is a dry run. Compare supported options and protocol versions on both endpoints.

Back to quick reference ↑

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Rsync Projectrsync(1) Manual Pagersync.samba.org
  2. Rsync ProjectRsync Documentationrsync.samba.org
  3. Rsync ProjectRsync Security Advisoriesrsync.samba.org
  4. Samba Projectrsync(1) Manual Sourcedownload.samba.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback