The essentials
Quick reference
One focused task per row. Jump to the related section for complete, working examples.
| Use | Syntax | Examples |
|---|---|---|
| Copy directory contents | rsync -a /srv/app/ /backup/app/ | View examples |
| Copy directory by name | rsync -a /srv/app /backup/ | View examples |
| Preserve ACLs and xattrs | sudo rsync -aAX /srv/app/ /backup/app/ | View examples |
| Stay on one filesystem | rsync -a --one-file-system /srv/ /backup/srv/ | View examples |
| Preview itemized changes | rsync -ain /srv/app/ /backup/app/ | View examples |
| Read exclude patterns | rsync -a --exclude-from=/etc/backup/app.exclude \
/srv/app/ /backup/app/ | View examples |
| Mirror with delayed deletion | rsync -ain --delete-delay --max-delete=100 /srv/app/ \
/backup/app/ | View examples |
| Retain replaced destination files | rsync -a --backup --backup-dir=../changed /srv/app/ \
/backup/current/ | View examples |
| Push through SSH | rsync -a -e 'ssh -o BatchMode=yes' /srv/app/ \
backup@store.example:/vault/app/ | View examples |
| Protect remote arguments | rsync -a -s ./data/ \
backup@store.example:'/vault/team data/' | View examples |
| Bound idle network time | rsync -a --timeout=120 --partial-dir=.rsync-partial \
/srv/app/ backup@store.example:/vault/app/ | View examples |
| Build a hard-linked snapshot | rsync -a --link-dest=../previous /srv/app/ \
/backup/snapshots/2026-08-12/ | View examples |
| Audit snapshot changes | rsync -ain --link-dest=../previous /srv/app/ \
/backup/snapshots/next/ | View examples |
| Checksum-compare a restore | rsync -nric --delete /backup/restore-test/ \
/srv/restore-reference/ | View examples |
| Preview a restore | rsync -ain /backup/snapshots/2026-08-12/ \
/srv/restore-test/ | View examples |
| Inspect local rsync version | rsync --version | View examples |
| Print transfer statistics | rsync -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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 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.
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.
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.
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.
Sources and further reading
References
Authoritative documentation used to verify and expand this cheat sheet.
Help us improve
Found a typo or missing example?
Tell us what would make this cheat sheet clearer, more complete, or more useful.



