| name | rsync |
| description | File synchronization, backup, and deployment with rsync. Use when user mentions "rsync", "sync files", "mirror directory", "incremental backup", "copy files to server", "deploy files", "remote sync", "backup to external drive", "exclude patterns", "dry run sync", "bandwidth limit transfer", or transferring files between local and remote systems efficiently. |
rsync Reference
Core Syntax
rsync [options] source destination
rsync -av /src/dir/ /dest/dir/
rsync -avz /local/dir/ user@host:/remote/dir/
rsync -avz user@host:/remote/dir/ /local/dir/
Trailing slash matters: /src/dir/ copies the contents of dir. /src/dir copies the directory itself into the destination.
Common Flags
-a, --archive
-v, --verbose
-z, --compress
-n, --dry-run
-P
--progress
-h, --human-readable
-r, --recursive
-u, --update
-c, --checksum
--stats
-q, --quiet
Local Sync Patterns
rsync -av --delete /src/ /dest/
rsync -av /src/ /dest/
rsync -av --include='*.jpg' --include='*/' --exclude='*' /src/ /dest/
rsync -avh --progress /src/ /dest/
rsync -av --no-relative /src/deep/path/file.txt /dest/
Remote Sync over SSH
rsync -avz /local/project/ user@server:/var/www/project/
rsync -avz user@server:/var/log/app/ /local/logs/
rsync -avz -e "ssh -p 2222" /local/ user@server:/remote/
rsync -avz -e "ssh -i ~/.ssh/deploy_key" /local/ user@server:/remote/
rsync -avz -e "ssh -c aes128-ctr" /local/ user@server:/remote/
rsync -av --compress-level=0 /local/media/ user@server:/remote/media/
Exclude and Include Patterns
rsync -av --exclude='*.log' /src/ /dest/
rsync -av --exclude='*.log' --exclude='.git' --exclude='node_modules' /src/ /dest/
rsync -av --exclude-from='exclude-list.txt' /src/ /dest/
rsync -av --include='*.py' --include='*/' --exclude='*' /src/ /dest/
rsync -av --filter='- *.log' --filter='- .git/' /src/ /dest/
rsync -av --filter='dir-merge .rsync-filter' /src/ /dest/
Delete Modes
rsync -av --delete /src/ /dest/
rsync -av --delete-after /src/ /dest/
rsync -av --delete-before /src/ /dest/
rsync -av --delete-excluded --exclude='*.tmp' /src/ /dest/
rsync -av --delete-during /src/ /dest/
rsync -av --delete --filter='P *.local' /src/ /dest/
Bandwidth Limiting
rsync -avz --bwlimit=1000 /src/ user@server:/dest/
rsync -avz --bwlimit=500 /src/ user@server:/dest/
rsync -avz --bwlimit=5m /src/ user@server:/dest/
Partial Transfers and Resume
rsync -av --partial /src/ /dest/
rsync -av --partial-dir=.rsync-partial /src/ /dest/
rsync -avP /src/ user@server:/dest/
rsync -av --append /src/ /dest/
rsync -av --append-verify /src/ /dest/
Backup Patterns
rsync -av --backup --backup-dir=/backups/$(date +%Y%m%d) /src/ /dest/
rsync -av --backup --suffix=".bak" /src/ /dest/
rsync -av --delete --link-dest=/backups/latest /src/ /backups/$(date +%Y%m%d)/
ln -nsf /backups/$(date +%Y%m%d) /backups/latest
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)
LATEST="$BACKUP_DIR/latest"
NEW="$BACKUP_DIR/$DATE"
rsync -av --delete \
${LATEST:+--link-dest="$LATEST"} \
/data/ "$NEW/"
rm -f "$LATEST"
ln -s "$NEW" "$LATEST"
ls -dt "$BACKUP_DIR"/2* | tail -n +8 | xargs rm -rf
rsync -av --delete --exclude='.Trash' /home/user/ /media/external/backup/
Deployment Workflows
rsync -avz --delete \
--exclude='.git' \
--exclude='.env' \
--exclude='node_modules' \
--exclude='.DS_Store' \
/local/site/build/ user@web:/var/www/html/
rsync -avzn --delete /local/site/build/ user@web:/var/www/html/
for server in web1 web2 web3; do
rsync -avz --delete /local/build/ deploy@$server:/var/www/html/ &
done
wait
rsync -avz --delete /local/build/ user@web:/var/www/html/ \
--rsync-path="sudo rsync" \
&& ssh user@web "sudo systemctl reload nginx"
rsync -avz /local/build/ user@web:/releases/$(date +%s)/
ssh user@web "ln -nsf /releases/$(date +%s) /var/www/current && sudo systemctl reload nginx"
Preserving File Attributes
rsync -a /src/ /dest/
rsync -rlptgoD /src/ /dest/
rsync -avH /src/ /dest/
rsync -avAX /src/ /dest/
rsync -av --no-owner --no-group /src/ /dest/
rsync -rltpv /src/ /dest/
Dry Run and Verbose Output
rsync -avn /src/ /dest/
rsync -avn --itemize-changes /src/ /dest/
rsync -av --stats /src/ /dest/
Common Recipes
rsync -avz --delete \
-e "ssh -i /ci/deploy_key -o StrictHostKeyChecking=no" \
--exclude='.git' --exclude='.env' \
./dist/ deploy@prod:/var/www/app/
mysqldump -u root mydb | gzip > /tmp/mydb.sql.gz
rsync -avz /tmp/mydb.sql.gz user@backup:/backups/db/mydb_$(date +%Y%m%d).sql.gz
rsync -av --delete \
--include='.bashrc' --include='.vimrc' --include='.gitconfig' \
--include='.config/***' --include='.ssh/config' \
--exclude='*' \
~/ user@other:~/
rsync -avz --delete --progress \
--exclude='.DS_Store' --exclude='Thumbs.db' \
~/Photos/ nas:/volume1/photos/
rsync -av --delete \
--exclude='node_modules' --exclude='dist' --exclude='.next' \
--exclude='__pycache__' --exclude='*.pyc' --exclude='.venv' \
/project/ /backup/project/
rsync -avu /dir_a/ /dir_b/
rsync -avu /dir_b/ /dir_a/
rsync -avP --bwlimit=2000 /local/large.iso user@server:/remote/
rsync Daemon Mode
rsync --daemon --config=/etc/rsyncd.conf
rsync -av rsync://syncuser@server/share/ /local/copy/
rsync -av server::share/ /local/copy/
rsync rsync://server/
Comparison with Other Tools
| Feature | rsync | scp | sftp | rclone |
|---|
| Incremental transfer | Yes | No | No | Yes |
| Resume partial | Yes | No | Yes | Yes |
| Compression | Yes | Yes | No | Yes |
| Delete remote extras | Yes | No | Manual | Yes |
| Cloud storage | No | No | No | Yes |
| Bandwidth limit | Yes | Yes (OpenSSH 9) | No | Yes |
| Preserve permissions | Yes | Yes | Yes | Limited |
| Filter/exclude | Yes | No | No | Yes |
Use rclone for cloud storage (S3, GCS, Dropbox). Use rsync for server-to-server and local sync.
Cron + rsync for Automated Backups
crontab -e
0 2 * * * rsync -a --delete /data/ /backups/daily/ >> /var/log/rsync-backup.log 2>&1
0 * * * * /usr/local/bin/rsync-hourly.sh
set -euo pipefail
SRC="/data/"
BASE="/backups"
STAMP=$(date +\%Y\%m\%d_\%H\%M)
LATEST="$BASE/latest"
NEW="$BASE/$STAMP"
rsync -a --delete --link-dest="$LATEST" "$SRC" "$NEW/" 2>> /var/log/rsync.log
rm -f "$LATEST"
ln -s "$NEW" "$LATEST"
0 3 * * * rsync -a --delete /data/ /backups/nightly/ 2>&1 || echo "Backup failed" | mail -s "rsync failure" admin@example.com
LOCKFILE="/tmp/rsync-backup.lock"
exec 200>"$LOCKFILE"
flock -n 200 || { echo "Already running"; exit 1; }
rsync -a --delete /data/ /backups/daily/
Troubleshooting
rsync -av --rsync-path="sudo rsync" /src/ user@server:/root-owned/
rsync -av --compress-level=0 /media/ user@server:/media/
rsync -av -e "ssh -c aes128-ctr -o Compression=no" /src/ user@server:/dest/
rsync -av --sockopts=SO_SNDBUF=65536,SO_RCVBUF=65536 /src/ /dest/
rsync -avc /src/ /dest/
rsync -avvv -e "ssh -v" /src/ user@server:/dest/
rsync -av --delete --max-delete=100 /src/ /dest/
rsync -av -e ssh "/path/with spaces/" "user@server:/path/with spaces/"
rsync -av --timeout=300 --contimeout=30 /src/ user@server:/dest/
rsync -avn --exclude='.git' /project/ user@server:/deploy/