
September 11, 2026
11 min read
By Kokil Thapa | Last reviewed: September 2026
rsync: Efficient File Sync and Backup is the first tool I reach for when a Laravel app, WordPress site, or legal-tech portal needs reliable file copies between servers. rsync sends only changed blocks over the wire, preserves permissions, and runs well over SSH on the Ubuntu boxes I maintain daily. If you handle Linux system administration for client sites, rsync belongs in your baseline toolkit alongside database dumps and off-site storage.
rsync -aHAX --delete --numeric-ids for mirror backups, --link-dest for space-efficient snapshots, and cron with logging for hands-off daily runs.How does rsync work for efficient file sync and backup?
rsync is not a generic copy command. It builds a file list on both sides, compares size and modification time, and transfers only the bytes that differ. On a second run, a 2 GB upload directory might move 40 MB instead of the full tree.
That delta behaviour is why rsync scales on small VPS hosts common in Nepal. Bandwidth costs real money. A nightly sync that touches only changed Blade views, uploaded PDFs, or WooCommerce product images keeps backup windows short.
rsync runs in two common modes:
- Push: the source server initiates the transfer to a remote destination.
- Pull: the backup server connects inward and copies data from production.
For production, I prefer pull backups when possible. The backup host holds the SSH key. Production does not need outbound credentials to cold storage. That limits blast radius if the app server is compromised.
Local sync vs remote sync over SSH
A local rsync between disks on one machine is useful before major upgrades. Remote sync uses -e ssh implicitly when you specify user@host:/path.
# Local mirror — useful before Laravel or WordPress upgrades
rsync -aHAX --delete \
/var/www/production/ \
/mnt/snapshot/production-$(date +%F)/
# Remote pull from backup server (preferred pattern)
rsync -aHAX --delete --numeric-ids \
-e "ssh -p 22 -i /root/.ssh/backup_pull_ed25519" \
deploy@203.0.113.10:/var/www/current/ \
/backups/sites/example.com/files/ Notice the trailing slash on the source path. /var/www/current/ copies the directory contents. Without the slash, rsync creates a nested current folder under the destination. That subtle difference has caused restore paths to drift on real deployments.
For deeper backup architecture, see Ubuntu server backup strategies and automated server backups complete setup.
What rsync flags should you use for production file backups?
Defaults are not enough for server backups. Production flags must preserve ownership, handle symlinks predictably, and delete stale files when you mirror a live tree.
Start with this baseline:
rsync -aHAX --delete --numeric-ids \
--info=stats2,progress2 \
--partial --partial-dir=.rsync-partial \
-e "ssh -o BatchMode=yes -o ConnectTimeout=30" \
SOURCE/ DEST/ Flag reference for daily operations
| Flag | Purpose | Production note |
|---|---|---|
-a | Archive mode: permissions, times, symlinks | Foundation for almost every backup job |
-H | Preserve hard links | Important for mail spools and some app caches |
-A | Preserve ACLs | Needed when apps use fine-grained permissions |
-X | Preserve extended attributes | Relevant for SELinux contexts on some hosts |
--delete | Remove dest files absent on source | Turns sync into a true mirror; test with dry-run first |
--numeric-ids | Skip UID/GID name mapping | Avoids ownership shifts when user tables differ |
--link-dest | Hard-link unchanged files | Enables cheap daily snapshots on one disk |
-z | Compress during transfer | Helps over slow cross-border links; skip on LAN NVMe |
--dry-run | Simulate without writing | Run before every new job or path change |
The official rsync manual at rsync.samba.org documents edge cases for ACL and xattr support across filesystems. Always confirm your backup volume supports the attributes you preserve.
Snapshot backups with --link-dest
Mirror-only backups overwrite yesterday. Snapshot-style retention keeps multiple dated copies without duplicating unchanged files. Each run hard-links identical inodes from the previous snapshot.
BACKUP_ROOT="/backups/example.com/files"
TODAY=$(date +%Y-%m-%d)
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
DEST="${BACKUP_ROOT}/${TODAY}"
LINK="${BACKUP_ROOT}/${YESTERDAY}"
mkdir -p "${BACKUP_ROOT}"
rsync -aHAX --delete --numeric-ids \
--link-dest="${LINK}" \
-e "ssh -i /root/.ssh/backup_pull_ed25519" \
deploy@203.0.113.10:/var/www/current/ \
"${DEST}/" On sister sites I maintain with Deployer 7 and GitLab CI, uploaded documents and shared storage paths sit outside the release symlink. Those paths belong in rsync jobs even when code deploys are zero-downtime. See how persistent storage fits into Notary Kathmandu deployment patterns and Adventure Third Pole Trek booking storage.
How do you automate rsync file backups with cron on Linux?
Manual rsync works once. Production needs scheduled jobs, exit-code checks, logs, and alert hooks. I wrap rsync in a small shell script and call it from cron on Ubuntu 22/24 servers.
- Create a dedicated backup user or restrict root SSH keys to pull-only commands.
- Store scripts in
/usr/local/bin/with mode750. - Write logs to
/var/log/backups/with logrotate config. - Run a
--dry-runafter any path or flag change. - Monitor exit codes — rsync returns non-zero on partial transfer.
Example backup script with locking
#!/usr/bin/env bash
set -euo pipefail
LOCK="/var/lock/rsync-example.lock"
LOG="/var/log/backups/example-files.log"
SOURCE="deploy@203.0.113.10:/var/www/shared/storage/"
DEST="/backups/example.com/storage/"
exec 9>"${LOCK}"
flock -n 9 || { echo "Backup already running"; exit 1; }
{
echo "=== $(date -Is) START ==="
rsync -aHAX --delete --numeric-ids \
--partial --partial-dir=.rsync-partial \
-e "ssh -i /root/.ssh/backup_pull_ed25519 -o BatchMode=yes" \
"${SOURCE}" "${DEST}"
echo "=== $(date -Is) OK ==="
} >>"${LOG}" 2>&1 Install the cron entry as root on the backup server:
# /etc/cron.d/example-files-backup
30 2 * * * root /usr/local/bin/backup-example-files.sh Pair file rsync with database dumps. A filesystem mirror without MySQL or PostgreSQL dumps gives you uploads but not orders, bookings, or client records. Read automate database backups on Linux and database backup strategies for small servers for the full picture.
For a focused walkthrough, see automate server backups with rsync and cron. When you need object storage, combine rsync with restic as described in offsite backups to S3 or R2 with rsync and restic.
How does rsync compare to scp, tar, and rclone for backups?
Teams often ask whether rsync is still the right choice in 2026. It depends on source, destination, and restore requirements. rsync excels at Unix-to-Unix incremental sync. It is weaker as a standalone encrypted archive format.
| Tool | Best for | Incremental | Typical weakness |
|---|---|---|---|
| rsync | Linux server trees over SSH | Yes — delta blocks | No built-in encryption at rest |
| scp | One-off file copies | No | Re-copies full files every run |
| tar + gzip | Portable archives, tape-style dumps | Only with extra tooling | Full archive rewrite unless scripted |
| rclone | S3, R2, Google Drive, multi-cloud | Yes | More moving parts than rsync-over-SSH |
For a head-to-head on cloud targets, read rsync vs rclone for server backups. My usual pattern: rsync to a local or colocated backup VPS, then rclone or restic to object storage. That split keeps production SSH simple and puts encryption at the off-site layer.
Ubuntu documents rsync usage in the Ubuntu Server documentation. Debian’s rsync package notes are another solid reference for flag behaviour across versions.
When rsync is the wrong primary tool
Skip rsync as your only backup layer when you need immutable point-in-time recovery, cross-platform restores to Windows desktops, or compliance archives with WORM retention. Use rsync for fast sync, then layer restic, Borg, or cloud-native snapshots for long-term retention.
If you migrate hosts, rsync also helps pre-cutover sync. See website migration services for the broader cutover checklist beyond file copy alone.
What are common rsync mistakes that break production backups?
Most backup failures I troubleshoot are configuration issues, not rsync bugs. These patterns show up repeatedly on client servers and on my own Deployer-managed hosts.
Trailing slash and path drift
A missing or extra trailing slash changes the destination tree shape. Always test with --dry-run -i and inspect the first ten lines of planned changes. Document the exact source and dest paths in your runbook.
Running --delete before verifying the source
--delete mirrors deletions. If nginx points at the wrong root or a mount fails silently, rsync can propagate an empty directory and wipe the backup mirror. Use --delete-delay or verify mount points in a pre-flight check.
# Pre-flight: abort if source mount missing
if ! mountpoint -q /var/www/current; then
echo "Source not mounted — aborting backup"
exit 2
fi Ignoring permissions and ownership
Restoring files without preserved UID, GID, and modes breaks Laravel storage/ writes and PHP-FPM uploads. Read Ubuntu file permissions explained and Linux file permissions and ACLs explained before stripping flags to “make it work”.
Backing up runtime noise
Exclude caches, sessions, and temporary upload chunks. They inflate transfer size and restore clutter.
# /etc/rsyncd.conf or --exclude-from file
/var/www/current/bootstrap/cache/*
/var/www/current/storage/framework/cache/*
/var/www/current/storage/framework/sessions/*
/var/www/current/storage/logs/*.log Generate strong passphrases for encrypted off-site layers with a password generator and store secrets outside the repo. Never commit backup SSH keys to Git — a topic that overlaps with stopping Git from tracking file permissions.
Restore drills nobody schedules
A backup job that never gets restored is a guess. Quarterly, pick one random snapshot. Restore files to a temp path. Confirm a PDF opens, an image serves, and Laravel storage is writable by www-data. Log the drill date.
Ongoing monitoring fits under support and maintenance and domain registration and hosting when clients want hands-off ops. For JSON config exports from backup manifests, a JSON formatter helps validate automation output quickly.
Key Takeaways
- Use
rsync -aHAX --delete --numeric-idsfor production mirrors, and always dry-run after path changes. - Prefer pull backups from a dedicated backup host with a restricted SSH key.
- Add
--link-destfor daily snapshots without multiplying disk use. - Pair file rsync with automated database dumps — files alone cannot restore transactional data.
- Exclude caches and logs; verify mounts before any job that uses
--delete. - Replicate local snapshots off-site with encryption via restic or rclone, then test restores quarterly.
People Also Ask
Is rsync still the best tool for Linux server backups in 2026?
Yes, for incremental file sync between Linux servers over SSH. rsync remains fast, widely packaged, and script-friendly on Ubuntu and Debian hosts. Pair it with encrypted off-site tooling when you need cloud retention or immutable archives.
Does rsync copy open or changing files safely?
rsync can miss changes to files that are actively written during the run. Quiesce apps or snapshot the filesystem first when consistency matters. Databases should be dumped with mysqldump or pg_dump, not copied live from data directories.
How much disk space do rsync snapshots with --link-dest use?
Space equals one full copy plus the sum of changed and new files across retained snapshots. Unchanged files share inodes via hard links. Retention policy and change rate determine growth, not the number of snapshot folders alone.
Can rsync backup Laravel storage and shared directories correctly?
Yes, when you include Deployer shared/ paths and preserve ownership with -aHAX --numeric-ids. Exclude storage/framework/cache and session temp dirs. Confirm www-data ownership after every test restore.
Build a backup stack you can restore from
rsync: Efficient File Sync and Backup earns its place because it is boring, fast, and inspectable. Delta sync keeps bandwidth costs down on Nepali and international links alike. Snapshot hard links give you history without buying new disks every month. The job is not done until database dumps, off-site copies, and restore drills sit beside the rsync cron entry.
If you want help wiring backups into a Laravel, WordPress, or legal-tech deployment pipeline, review the portfolio and reach out via contact us. I set up rsync jobs, retention, and monitoring on production Linux hosts regularly — so the next incident is a restore, not a rebuild.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

