I still remember the first time I tried to sync a few hundred gigabytes of user files between servers using scp. Six hours later, my terminal was still churning away, and when the connection dropped at 94%, I wanted to throw my laptop out the window. That’s when a senior engineer walked by and asked, “Why aren’t you using rsync?”
That question changed everything. Rsync isn’t just another file transfer command – it’s the tool that makes impossible backup jobs manageable and turns multi-hour syncs into minutes. After a decade of system administration, I reach for rsync almost daily, and I’m going to show you exactly how to use it.
What is Rsync and Why It Beats Everything Else
Rsync (remote sync) is a file synchronization and transfer utility that’s been around since 1996, and it’s still the best at what it does. Here’s what makes it special: it only transfers the differences between source and destination files, not entire files every time.
Think about syncing a 10GB database backup that changes by 50MB daily. With scp, you’d transfer all 10GB every single time. With rsync? Just that 50MB delta. According to performance comparisons on Stack Overflow, rsync can be orders of magnitude faster – one test showed rsync completing a job in 5.6 seconds versus 6 minutes for scp.
The delta-transfer algorithm is rsync’s secret weapon. It calculates checksums for file blocks and only transmits changed portions. This means faster transfers, less bandwidth usage, and the ability to resume interrupted operations without starting over.

Installing Rsync (It’s Probably Already There)
On most modern Linux distributions, rsync comes pre-installed. Check by running:
rsync --versionIf you get a version number, you’re good to go. If not, install it quickly:
# Ubuntu/Debian
sudo apt update && sudo apt install rsync
# RHEL/CentOS/Fedora
sudo dnf install rsync
# Arch Linux
sudo pacman -S rsyncThe Basic Rsync Syntax (And the Trailing Slash That Trips Everyone Up)
Before we dive into examples, you need to understand rsync’s basic syntax:
rsync [OPTIONS] SOURCE DESTINATIONSimple enough, right? But here’s where it gets interesting – and where I see beginners mess up constantly. That trailing slash on your source path? It completely changes what rsync does.
With a trailing slash: Rsync copies the contents of the directory.
rsync -av /home/user/documents/ /backup/This copies everything inside documents/ directly into /backup/, so you end up with /backup/file1.txt, /backup/file2.txt, etc.
Without a trailing slash: Rsync copies the directory itself.
rsync -av /home/user/documents /backup/This creates /backup/documents/ and puts the files inside that, resulting in /backup/documents/file1.txt, /backup/documents/file2.txt, etc.
I’ve seen this simple difference cause hours of confusion and duplicate files everywhere. Memorize it now, thank me later.
Essential Rsync Options You’ll Actually Use
Rsync has about a hundred different options, but in reality, you’ll use these core ones 95% of the time:
Archive Mode (-a): Your Default Go-To
The -a flag is shorthand for “archive mode” and it’s what you should use for almost everything. It’s actually a combination of multiple options:
rsync -a source/ destination/Archive mode preserves:
- Permissions – File modes stay intact
- Timestamps – Modification times are preserved
- Symbolic links – Links aren’t dereferenced
- Ownership – User and group ownership (when run as root)
- Recursive copying – Subdirectories are included
Without -a, you might restore a backup only to find your executables aren’t executable anymore. Not fun. As Red Hat’s sysadmin guide points out, archive mode is essential for maintaining file integrity.
Verbose Mode (-v): See What’s Happening
Add -v to get feedback about what rsync is doing. Use -vv for more detail, or -vvv when you’re troubleshooting and need all the information:
rsync -av source/ destination/Compression (-z): Speed Up Remote Transfers
When transferring over the network, compression can significantly reduce transfer time if bandwidth is your bottleneck:
rsync -avz source/ user@remote-host:/destination/The -z flag compresses data during transmission and decompresses it on arrival. For text files and uncompressed data, I’ve seen this cut transfer times in half.
Progress (–progress): Know How Long You’re Waiting
Nothing’s worse than staring at a blank terminal wondering if rsync crashed or if it’s still working:
rsync -av --progress source/ destination/This shows you a progress bar for each file and overall statistics. For big transfers, I always add this flag to maintain my sanity.
How to Use Rsync Locally: Basic File Synchronization
Let’s start simple – syncing files on the same machine. This is perfect for backups to external drives or organizing data between directories.
Here’s a real-world example I use constantly – backing up my home directory to an external USB drive:
rsync -av --progress /home/alex/ /mnt/backup-drive/home-backup/This preserves everything, shows progress, and only copies changed files on subsequent runs. The first sync might take a while, but future syncs are blazingly fast.
Want to exclude certain directories? Use --exclude:
rsync -av --progress \
--exclude='node_modules' \
--exclude='.cache' \
--exclude='*.tmp' \
/home/alex/projects/ /mnt/backup-drive/projects-backup/I always exclude cache directories and temporary files. No point backing up node_modules when you can reinstall them in seconds.
Remote Transfers: Syncing Between Servers with SSH
This is where rsync really shines. By default, rsync uses SSH for remote connections, which means your data is encrypted in transit. But you need to set it up properly.
First, make sure you have SSH key authentication configured between the servers. Password prompts are annoying and impractical for automated jobs.
Syncing to a Remote Server
rsync -avz /local/directory/ user@192.168.1.50:/remote/directory/The -z flag becomes much more important here since you’re transferring over the network. Let compression do its job.
Syncing from a Remote Server
Just flip the order:
rsync -avz user@192.168.1.50:/remote/directory/ /local/directory/Using a Non-Standard SSH Port
If your SSH runs on a different port (and it should for security), specify it with -e:
rsync -avz -e "ssh -p 2222" source/ user@remote-host:/destination/The Delete Flag: Handle With Extreme Care
By default, rsync never deletes files at the destination. If you delete something from the source, rsync leaves the old copy at the destination untouched. This is a safety feature.
But sometimes you want true mirroring – making the destination exactly match the source. That’s where --delete comes in:
rsync -av --delete source/ destination/This removes any files from the destination that don’t exist in the source. It’s powerful and dangerous.
Critical warning: Always, always do a dry run first with --delete. I’ve seen people accidentally nuke production data because they got their source and destination backwards.
Dry Run: Test Before You Wreck
The --dry-run or -n flag is your safety net. It shows you exactly what rsync would do without actually doing it:
rsync -avn --delete source/ destination/This outputs the list of changes that would occur. Read it carefully. Especially when using --delete, as DigitalOcean’s rsync tutorial emphasizes, dry runs prevent catastrophic mistakes.
I have a policy: any rsync command I haven’t run a hundred times before gets a dry run first. It’s saved me more than once.
Real-World Use Cases I Rely On
Let me share some actual rsync commands I use in production environments.
Daily Incremental Backups
I set this up as a cron job that runs nightly:
#!/bin/bash
rsync -avz --delete \
--exclude='*.log' \
--exclude='/tmp/*' \
/var/www/ \
backup-server:/backups/www-$(date +%Y%m%d)/This creates dated backup directories and only transfers changes. The first backup might be 100GB, but subsequent runs only transfer a few megabytes.
Deploying Website Updates
When I need to push code from staging to production:
rsync -avz --delete \
--exclude='.git' \
--exclude='config.local.php' \
/var/www/staging/ \
production-server:/var/www/production/The --exclude flags ensure I don’t overwrite environment-specific config files or sync version control directories.
Mirroring Large Media Libraries
For syncing terabytes of media files where disk space is at a premium:
rsync -av --progress \
--partial \
--timeout=300 \
/media/original/ media-server:/media/archive/The --partial flag keeps partially transferred files if the connection drops, and --timeout prevents hung connections from stalling the transfer forever.
Advanced Options That Solve Specific Problems
Using Checksums Instead of Timestamps
Normally, rsync decides if files need updating based on size and modification time. But if you’ve got files with incorrect timestamps (happens more than you’d think), use checksums:
rsync -avc source/ destination/The -c flag forces rsync to calculate and compare checksums for every file. It’s slower but catches files that changed but have identical timestamps.
Bandwidth Limiting
If you’re running rsync during business hours and don’t want to saturate the network connection:
rsync -av --bwlimit=5000 source/ destination/This limits bandwidth to 5000 KB/s (about 5 MB/s). Adjust based on your available bandwidth.
Preserving Hard Links
For systems with lots of hard links (like some backup schemes):
rsync -aH source/ destination/The -H flag preserves hard links, which can save massive amounts of space.
Common Mistakes That Will Bite You
Let me save you from the errors I’ve made (and seen others make) over the years:
Mistake #1: Forgetting the trailing slash. Covered this earlier, but it bears repeating. The trailing slash matters. A lot.
Mistake #2: Using –delete without –dry-run first. This is how production data disappears. Don’t be that person.
Mistake #3: Not using absolute paths in cron jobs. Relative paths work differently in cron environments. Always use absolute paths for automated rsync jobs.
Mistake #4: Syncing while files are actively changing. If you’re backing up a running database, rsync can’t guarantee consistency. Stop the service, create a snapshot, or use proper database backup tools.
Mistake #5: Forgetting about file permissions. If you’re running rsync without root privileges and trying to preserve ownership, it won’t work. You’ll get permission errors or silently wrong ownership.
Mistake #6: Not excluding unnecessary files. I’ve seen people back up gigabytes of browser cache, temp files, and Docker images. Exclude that stuff and save time and space.
Troubleshooting Rsync Issues
When rsync doesn’t work as expected, here’s my debugging process:
Connection failures: Verify SSH connectivity first. Can you manually SSH to the remote host? Check your SSH keys and known_hosts file.
Permission denied errors: Check file ownership and permissions on both sides. The destination directory needs to be writable by your user. Use ls -la to investigate.
Slow transfers: Try adding -z for compression. Check network bandwidth. Consider if the problem is actually disk I/O, not network speed.
Files not syncing: Use -vv for verbose output to see what rsync is actually doing. Check if files are being excluded by patterns you didn’t intend.
“Protocol version mismatch” error: Your local and remote rsync versions are too different. Update rsync on both systems.
Rsync vs Other Tools: When to Use What
People often ask me when to use rsync versus tar, scp, or other tools.
Use rsync when:
- You need to sync files repeatedly (backups, deployments)
- You’re transferring large amounts of data and want efficiency
- You need to preserve file metadata perfectly
- Your transfers might get interrupted and need to resume
Use scp when:
- You’re doing a one-time transfer of a few files
- Simplicity matters more than efficiency
- You don’t need synchronization features
Use tar when:
- You need to archive files into a single file
- You’re moving files between systems without SSH access
- You want compression in the archive itself
According to Linux administration guides, rsync has essentially replaced scp for most serious system administration work because of its efficiency and flexibility.
Automating Rsync with Cron
Once you’ve got your rsync command working perfectly, automate it. Here’s a crontab entry for nightly backups at 2 AM:
0 2 * * * /usr/bin/rsync -avz --delete --log-file=/var/log/rsync-backup.log /data/ backup-server:/backups/data/ 2>&1 | /usr/bin/logger -t rsync-backupA few things to note here:
- I’m using the full path to rsync (
/usr/bin/rsync) because cron has a minimal environment - The
--log-fileoption creates a detailed log you can check later - I’m piping errors to syslog with logger so I get notified if something breaks
For more complex scheduling needs, check out my complete guide to cron jobs.
Security Considerations You Shouldn’t Ignore
Rsync over SSH is secure by default, but you can still make mistakes:
Use SSH keys, not passwords. Seriously. Automated rsync jobs with password authentication are a security nightmare and don’t work well anyway.
Restrict SSH access. Create a dedicated backup user with limited privileges and a restricted shell. Don’t run rsync as root unless absolutely necessary.
Encrypt your backup destinations. Rsync encrypts data in transit over SSH, but it doesn’t encrypt data at rest. If you’re backing up to external drives or remote servers, consider encryption at the filesystem level.
Monitor your rsync jobs. Failed backups are worse than no backups because you think you’re protected when you’re not. Set up alerts for failed cron jobs.
My Personal Rsync Workflow
After years of refinement, here’s how I approach any new rsync task:
- Start with the basics: Get the command working locally first with
rsync -av - Add exclusions: Figure out what I don’t need and exclude it
- Test with dry-run: Always run
--dry-runto verify behavior - Run it manually: Execute the real command and watch it carefully the first time
- Verify the results: Check the destination and make sure everything looks right
- Automate if needed: Add to cron and set up logging and alerts
- Document it: Future me will thank present me for leaving a comment about what this does
This methodical approach has saved me from countless disasters. Rsync is powerful enough that you can really hurt yourself if you’re careless.
The Bottom Line on Rsync
Learning how to use rsync properly is one of those fundamental Linux skills that separates people who occasionally use Linux from people who actually administer systems professionally. It’s not the flashiest tool – there’s no GUI, no fancy dashboard – but it’s incredibly reliable and efficient at what it does.
I’ve been using rsync for over a decade, and I still discover new use cases and clever options. The beauty is that you don’t need to master everything about it to get value. Start with rsync -av source/ destination/, add --delete when you need true mirroring, throw in -z for remote transfers, and you’ve got 90% of what you’ll ever need.
The remaining 10% you’ll learn as you encounter specific problems, and that’s fine. Rsync’s man page is 4,000 lines long. Nobody knows all of it, and nobody needs to.
What matters is that when you need to move files efficiently, preserve metadata perfectly, or create reliable backups, you know rsync can do it and you know the basic patterns to start from. The rest is refinement.
Now go forth and sync those files. Just remember: test with --dry-run first, pay attention to that trailing slash, and never, ever run --delete on production without triple-checking your source and destination paths.







