rsync is the standard file synchronization tool on Linux and Unix systems. It transfers only the differences between source and destination files (delta-transfer algorithm), making it faster than copying everything with cp or scp. This guide covers rsync syntax, common flags, local and remote sync, exclude patterns, mirroring, dry runs, bandwidth limiting, and scheduled backups with cron.

Install rsync

rsync is pre-installed on most Linux distributions. If missing, install it:

# RHEL 10/9, Rocky Linux, AlmaLinux, Fedora
sudo dnf -y install rsync

# Debian, Ubuntu
sudo apt update && sudo apt -y install rsync

# Arch Linux, Manjaro
sudo pacman -S rsync

# FreeBSD
sudo pkg install rsync

Verify the installed version:

$ rsync --version | head -1
rsync  version 3.3.0  protocol version 32

Basic Syntax

# Local sync
rsync [OPTIONS] SOURCE DESTINATION

# Push to remote
rsync [OPTIONS] SOURCE USER@HOST:DESTINATION

# Pull from remote
rsync [OPTIONS] USER@HOST:SOURCE DESTINATION

Common rsync Options

FlagDescription
-aArchive mode – preserves permissions, ownership, timestamps, symlinks, recursion (equals -rlptgoD)
-vVerbose output
-zCompress data during transfer
-hHuman-readable file sizes
-PShow progress + keep partial files (equals --progress --partial)
--progressShow per-file transfer progress
--info=progress2Show overall transfer progress (percentage of total)
-n, --dry-runSimulate the transfer without making changes
--deleteDelete files in destination that don’t exist in source
-eSpecify remote shell (e.g., -e 'ssh -p 2222')
--excludeExclude files matching a pattern
--includeInclude files matching a pattern
--bwlimitLimit bandwidth in KB/s
--backupMake backups of overwritten files
--max-sizeSkip files larger than given size
--min-sizeSkip files smaller than given size
-WCopy whole files (skip delta algorithm)
-qQuiet mode – suppress non-error messages

The most common combination is rsync -avhP which gives you archive mode, verbose output, human-readable sizes, and progress display.

The Trailing Slash Rule

The trailing slash on the source path changes rsync behavior significantly. This is one of the most common sources of confusion:

# WITH trailing slash: copies CONTENTS of mydir into /backup/
rsync -avh /home/admin/mydir/ /backup/
# Result: /backup/file1.txt, /backup/file2.txt

# WITHOUT trailing slash: copies the DIRECTORY itself into /backup/
rsync -avh /home/admin/mydir /backup/
# Result: /backup/mydir/file1.txt, /backup/mydir/file2.txt

The destination path is not affected by trailing slashes – only the source matters.

Local Sync Examples

Copy a single file to another directory:

rsync -avh backup.tar.gz /tmp/

Sync the contents of one directory to another with progress:

rsync -avhP /home/admin/project/ /mnt/backup/project/

Show overall transfer progress instead of per-file:

rsync -avh --info=progress2 /home/admin/project/ /mnt/backup/project/

Remote Sync over SSH

rsync uses SSH as its default transport. Push local files to a remote server:

rsync -avhP /home/admin/project/ [email protected]:/backup/project/

Pull files from a remote server to local:

rsync -avhP [email protected]:/var/log/nginx/ /tmp/nginx-logs/

Rsync with Custom SSH Port

If the remote server runs SSH on a non-standard port, use the -e flag. For example, if SSH is on port 2222 (see our guide on changing the SSH port):

rsync -avhP -e 'ssh -p 2222' /home/admin/project/ [email protected]:/backup/project/

Rsync with a Specific SSH Key

rsync -avhP -e 'ssh -i ~/.ssh/backup_key' /data/ [email protected]:/backup/data/

Dry Run – Test Before Syncing

Always test with --dry-run (or -n) before running destructive operations like --delete. This shows what would happen without making any changes:

rsync -avhn --delete /home/admin/project/ [email protected]:/backup/project/

Review the output carefully. Lines prefixed with deleting show files that would be removed from the destination.

Mirror with –delete

The --delete flag makes the destination an exact mirror of the source. Files that exist in the destination but not in the source are removed:

rsync -avhP --delete /home/admin/website/ [email protected]:/var/www/website/

This is the standard approach for deploying websites and keeping backup mirrors in sync. Always do a --dry-run first to avoid accidental data loss.

Exclude and Include Patterns

Skip specific files or directories during transfer:

# Exclude a single directory
rsync -avhP --exclude='node_modules' /home/admin/project/ /backup/project/

# Exclude multiple patterns
rsync -avhP --exclude='*.log' --exclude='*.tmp' --exclude='.git' /home/admin/project/ /backup/project/

# Include only specific files, exclude the rest
rsync -avhP --include='*.conf' --exclude='*' /etc/ /backup/configs/

For complex exclude rules, use a file:

vi exclude-list.txt

Add one pattern per line:

node_modules/
*.log
*.tmp
.git/
__pycache__/
.env

Then reference the file:

rsync -avhP --exclude-from='exclude-list.txt' /home/admin/project/ /backup/project/

Limit Transfer by File Size

Skip files that are larger or smaller than a threshold:

# Skip files larger than 100MB
rsync -avhP --max-size='100m' /data/ [email protected]:/backup/data/

# Skip files smaller than 10KB
rsync -avhP --min-size='10k' /data/ [email protected]:/backup/data/

Bandwidth Limiting

Prevent rsync from saturating the network link during production hours:

# Limit to 5 MB/s
rsync -avhP --bwlimit=5000 /data/ [email protected]:/backup/data/

# Limit to 1 MB/s
rsync -avhP --bwlimit=1000 /data/ [email protected]:/backup/data/

The value is in KB/s. Use 5000 for 5 MB/s, 10000 for 10 MB/s.

Resume Partial Transfers

If a large transfer gets interrupted, the -P flag (which equals --partial --progress) keeps partially transferred files and resumes from where it stopped:

rsync -avhP /data/large-backup.tar.gz [email protected]:/backup/

Without --partial, rsync deletes incomplete files and starts over on the next run.

Backup with Versioning

The --backup flag keeps a copy of overwritten files instead of replacing them. Combined with --backup-dir, it creates a versioned backup structure:

rsync -avhP --delete --backup --backup-dir=/backup/incremental/$(date +%F) \
  /home/admin/project/ /backup/current/project/

This keeps /backup/current/ as an exact mirror while saving overwritten files in dated subdirectories under /backup/incremental/.

Scheduled Backups with Cron

Automate rsync by adding it to cron. Open the crontab editor:

crontab -e

Add a job to run daily at 2 AM:

# Daily backup at 2 AM
0 2 * * * rsync -avh --delete /home/admin/project/ [email protected]:/backup/project/ >> /var/log/rsync-backup.log 2>&1

For more sophisticated backup automation, see our guide on bash scripts for automating Linux backups. For real-time sync, check rsync with lsyncd for live file synchronization.

Quick Reference

TaskCommand
Local copy with progressrsync -avhP src/ dest/
Push to remotersync -avhP src/ user@host:dest/
Pull from remotersync -avhP user@host:src/ dest/
Mirror (exact copy)rsync -avhP --delete src/ dest/
Dry runrsync -avhn --delete src/ dest/
Custom SSH portrsync -avhP -e 'ssh -p 2222' src/ user@host:dest/
Exclude patternsrsync -avhP --exclude='*.log' src/ dest/
Limit bandwidthrsync -avhP --bwlimit=5000 src/ dest/
Resume partialrsync -avhP src/ dest/ (the -P enables resume)

Conclusion

rsync is the go-to tool for file synchronization, backups, and deployments on Linux. The delta-transfer algorithm means only changed bytes are sent over the network, making it far more efficient than scp for recurring transfers. For production use, always test with --dry-run before using --delete, and consider combining rsync with cron for automated nightly backups.

Related guides:

LEAVE A REPLY

Please enter your comment!
Please enter your name here