Rsync Options and Flags
This is a comprehensive reference for rsync flags, organized by purpose. Each flag includes what it does, when to use it, and practical examples.
For most server tasks, start with -avzP and add flags as needed:
rsync -avzP /source/ /destination/
This gives you archive mode, verbose output, compression, and progress display.
Archive and Basic Flags
These are the flags you'll use in virtually every rsync command.
| Flag | Name | Description |
|---|---|---|
-a | Archive | Combines -rlptgoD: recursive, symlinks, permissions, timestamps, group, owner, devices |
-v | Verbose | Shows each file being transferred |
-r | Recursive | Recurse into subdirectories (included in -a) |
-n | Dry run | Preview changes without transferring anything |
-P | Progress + partial | Shows transfer progress and keeps partial files for resume |
-h | Human-readable | Shows file sizes in KB/MB/GB instead of bytes |
What Archive Mode (-a) Actually Does
The -a flag is a shortcut for seven individual flags:
| Component | Flag | What It Preserves |
|---|---|---|
| Recursive | -r | Descends into directories |
| Symlinks | -l | Copies symlinks as symlinks |
| Permissions | -p | File permissions (rwx bits) |
| Times | -t | Modification timestamps |
| Group | -g | Group ownership |
| Owner | -o | User ownership (requires root) |
| Devices | -D | Device and special files |
Archive mode (-a) is the correct choice for almost all server sync operations. It preserves the metadata that web servers, application runtimes, and system services depend on.
Examples
# Standard backup — archive + verbose
rsync -av /var/www/html/ /backup/www/
# Dry run — see what would happen without doing anything
rsync -av --dry-run /var/www/html/ /backup/www/
# Full combo — archive, verbose, compress, progress + resume
rsync -avzP /var/www/html/ user@backup-server:/backups/www/
Compression and Bandwidth
Control how much data goes over the network and how fast.
| Flag | Description | When to Use |
|---|---|---|
-z | Compress data during transfer | Remote transfers over the internet |
--compress-level=N | Set compression level (1–9) | Fine-tune CPU vs bandwidth trade-off |
--bwlimit=KBPS | Limit bandwidth in KB/s | Prevent saturating shared connections |
--whole-file | Disable delta transfer (copy full files) | Sometimes faster on LAN |
When to Use Compression
| Scenario | Use -z? | Why |
|---|---|---|
| Remote transfer over internet | Yes | Reduces data sent over slow links |
| Transfer between LAN servers | Usually not | Network is fast; compression adds CPU overhead |
Already-compressed files (.gz, .zip, .jpg) | No | Can't compress further; wastes CPU |
| Text-heavy files (code, configs, logs) | Yes | Text compresses very well |
Examples
# Compress for remote transfer
rsync -avz /var/www/html/ user@remote:/var/www/html/
# Limit bandwidth to 500 KB/s to avoid saturating the connection
rsync -avz --bwlimit=500 /var/backups/ user@remote:/backups/
# High compression for slow connections
rsync -avz --compress-level=9 /var/www/ user@remote:/var/www/
# Disable delta transfer for LAN (sometimes faster)
rsync -av --whole-file /source/ /nas/backup/
SSH and Connection Options
Rsync uses SSH by default for remote transfers. These flags control the connection.
| Flag | Description | Example |
|---|---|---|
-e "ssh" | Specify remote shell (default is SSH) | Usually implicit |
-e "ssh -p 2222" | Use non-standard SSH port | For servers on custom ports |
-e "ssh -i ~/.ssh/key" | Use specific SSH key | For dedicated backup keys |
--rsync-path="sudo rsync" | Run rsync as sudo on remote | When remote user lacks permissions |
Examples
# Non-standard SSH port
rsync -avz -e "ssh -p 2222" /var/www/ user@server:/var/www/
# Specific SSH key for backup automation
rsync -avz -e "ssh -i ~/.ssh/backup_key" /var/www/ backupuser@remote:/backups/
# Remote rsync with sudo (when remote user can't read files)
rsync -avz --rsync-path="sudo rsync" /var/www/ user@server:/var/www/
Always use SSH key-based authentication for automated rsync operations. Never store passwords in scripts. For production automation, create a dedicated SSH key pair with limited permissions.
Filtering: Exclude and Include
Control which files and directories are transferred.
| Flag | Description |
|---|---|
--exclude=PATTERN | Skip files/directories matching the pattern |
--include=PATTERN | Force inclusion of matching files (overrides excludes) |
--exclude-from=FILE | Read exclude patterns from a file |
--include-from=FILE | Read include patterns from a file |
--filter=RULE | Apply complex filter rules |
Common Exclude Patterns
# Skip cache directories and log files
rsync -av \
--exclude='cache/' \
--exclude='*.log' \
--exclude='*.tmp' \
/var/www/html/ /backup/www/
# Skip version control and build artifacts
rsync -av \
--exclude='.git/' \
--exclude='node_modules/' \
--exclude='vendor/' \
--exclude='__pycache__/' \
/var/www/app/ /backup/app/
# Skip environment files (contain secrets)
rsync -av \
--exclude='.env' \
--exclude='*.pem' \
--exclude='*.key' \
/var/www/app/ user@staging:/var/www/app/
Using an Exclude File
Create a reusable exclude list:
# Build artifacts
.git/
node_modules/
vendor/
__pycache__/
# Temporary files
*.log
*.tmp
*.swp
cache/
# Secrets
.env
*.pem
*.key
rsync -av --exclude-from=/etc/rsync/excludes.txt /var/www/ /backup/www/
Using an exclude file keeps your rsync commands clean and makes it easy to maintain consistent patterns across multiple backup scripts.
Deletion and Synchronization
These flags control how rsync handles files that exist at the destination but not at the source.
| Flag | Description | Safety Level |
|---|---|---|
| (no flag) | Don't delete anything — only add/update | Safest |
--delete | Delete destination files not in source | Destructive |
--delete-before | Delete before transfer starts | Mirror accuracy |
--delete-during | Delete while transferring | Faster for large transfers |
--delete-after | Delete after transfer completes | Safer for partial syncs |
--ignore-existing | Never overwrite existing destination files | Very safe |
--existing | Only update files that already exist at destination | Safe |
--update | Skip files newer at destination | Safe |
--deleteThe --delete flag makes rsync a mirror tool — it makes the destination exactly match the source by removing files from the destination that don't exist in the source.
Always:
- Run with
--dry-runfirst - Verify the output carefully
- Have a separate backup before using
--delete
# ALWAYS preview first
rsync -av --delete --dry-run /source/ /destination/
# Only execute after verifying the dry run output
rsync -av --delete /source/ /destination/
Examples
# Mirror production to staging (exact copy)
rsync -avz --delete /var/www/html/ user@staging:/var/www/html/
# Add new files without touching existing ones
rsync -av --ignore-existing /source/ /destination/
# Only update files that already exist (no new files)
rsync -av --existing /source/ /destination/
# Skip files that are newer at the destination
rsync -av --update /source/ /destination/
Permissions and Ownership
Control file metadata at the destination.
| Flag | Description | Root Required? |
|---|---|---|
-p | Preserve permissions | No |
-o | Preserve owner | Yes |
-g | Preserve group | Depends |
-t | Preserve modification times | No |
--chown=USER:GROUP | Set ownership on destination | Yes |
--chmod=MODE | Set permissions on destination | No |
-a | All of the above (archive mode) | -o needs root |
Examples
# Sync and set ownership for web server
rsync -av --chown=www-data:www-data /deploy/app/ /var/www/html/
# Sync and set directory/file permissions
rsync -av --chmod=D755,F644 /deploy/app/ /var/www/html/
# Preserve everything (requires root)
sudo rsync -av /source/ /destination/
After syncing application files, ensure the web server user (often www-data for Nginx/Apache) has read access. Use --chown during sync or fix permissions afterward:
rsync -av --chown=www-data:www-data --chmod=D755,F644 \
/deploy/app/ /var/www/html/
Progress, Logging, and Statistics
Monitor transfers and keep records.
| Flag | Description |
|---|---|
--progress | Show per-file transfer progress |
--stats | Print a summary of transfer statistics at the end |
--log-file=PATH | Write detailed log to a file |
-v / -vv / -vvv | Increasing levels of verbosity |
--itemize-changes | Show exactly what changed for each file |
Examples
# Show detailed statistics after backup
rsync -avz --stats /var/www/ /backup/www/
# Log all activity to a file (great for cron jobs)
rsync -avz --log-file=/var/log/rsync-backup.log /var/www/ /backup/www/
# Show exactly what changed and why
rsync -av --itemize-changes /source/ /destination/
Advanced Flags
| Flag | Description | Use Case |
|---|---|---|
--link-dest=DIR | Hard-link unchanged files to reference directory | Space-efficient incremental backups |
--backup | Move overwritten files to backup location | Versioned backups |
--backup-dir=DIR | Where to store backup copies | Organize old versions |
--remove-source-files | Delete source files after successful transfer | Move operations |
--partial-dir=DIR | Store partial transfers in separate directory | Resume on flaky connections |
--ignore-times | Transfer all files regardless of timestamp/size | Force complete resync |
--checksum | Compare files by checksum instead of timestamp/size | Verify integrity |
--max-size=SIZE | Skip files larger than SIZE | Exclude large files |
--min-size=SIZE | Skip files smaller than SIZE | Skip tiny files |
Incremental Backup with Hard Links (--link-dest)
This is one of rsync's most powerful features — create daily snapshots that share disk space:
# Yesterday's backup is the reference
rsync -av --link-dest=/backup/2024-01-14/ \
/var/www/html/ /backup/2024-01-15/
Unchanged files are hard-linked to the previous backup (using zero extra disk space). Only changed files consume new storage.
Common Flag Combinations
| Task | Command |
|---|---|
| Standard backup | rsync -avzP /source/ /destination/ |
| Safe preview | rsync -av --dry-run /source/ /destination/ |
| Mirror (exact copy) | rsync -avz --delete /source/ /destination/ |
| Deploy without secrets | rsync -avz --exclude='.env' /app/ user@prod:/app/ |
| Bandwidth-limited remote | rsync -avz --bwlimit=500 /source/ user@remote:/dest/ |
| Incremental snapshot | rsync -av --link-dest=/backup/prev/ /source/ /backup/today/ |
| Log everything | rsync -avz --log-file=/var/log/rsync.log /source/ /dest/ |
| Web-safe permissions | rsync -av --chown=www-data:www-data --chmod=D755,F644 /app/ /var/www/ |
Common Pitfalls
| Pitfall | Risk | Prevention |
|---|---|---|
Using --delete without --dry-run | Accidental permanent deletion | Always preview first |
Forgetting -a (archive mode) | Lost permissions, timestamps, ownership | Use -a for all server operations |
Using -z on LAN transfers | Wasted CPU, slower transfers | Skip compression on fast networks |
--ignore-errors in production | Silently skips corrupt files | Only use for non-critical data |
--inplace on active files | Corrupts files being read by applications | Use only for offline file updates |
Missing --chown after deployment | Web server can't read synced files | Set correct ownership during sync |
What's Next
- Operators and Keywords — Advanced path modifiers and filter syntax
- Exclude and Include Patterns — Deep dive into filtering
- Security and Permissions — Production permission management