If you’ve ever copied files between machines and thought “there has to be a better way,” you’re about to meet your new favorite command. Learning how to use rsync in Linux changed the way I manage every server in my homelab. It’s fast, it’s smart, and once you understand a few key flags, you’ll never go back to basic copy commands. Whether you’re syncing files locally or pushing backups to a remote server, rsync handles it all. It’s also the backbone of most automatic backups in Linux.

What Is rsync and Why Should You Use It?
rsync (short for “remote sync”) has been around since 1996. Created by Andrew Tridgell and Paul Mackerras, it’s now maintained by Wayne Davison and has the largest installed base of any open-source backup utility. That’s not hype — it’s just what happens when a tool solves a real problem well for nearly three decades.
The magic is rsync’s delta-transfer algorithm. Instead of copying entire files every time, rsync compares source and destination and only sends the parts that changed. Your first sync might take a few seconds. The next one? Fractions of a second, because almost nothing needs to move.
I remember the first time this clicked for me. I was syncing about 40GB of project files from my workstation to my homelab NAS. The initial transfer took a while, sure. But when I ran the same rsync command again after changing a handful of files, it finished in under a second. That was the moment I stopped using cp for anything beyond quick local copies.
Get a VPS from as low as $11/year! WOW!
rsync vs. cp vs. scp: What’s the Difference?
Here’s the quick breakdown:
cp: Local only. Copies everything, every time. No network support, no change detection.- SCP command: Works over SSH for remote copies, but transfers whole files every time. A repeated transfer takes about 1.5 seconds — even if nothing changed.
rsync: Works locally AND remotely. First transfer ~3.8 seconds, repeat transfers ~0.3 seconds because only diffs get sent. Supports resuming interrupted transfers with--partial.
If you only copy files once, scp is fine. But the moment you need to keep two locations in sync, rsync wins by a landslide.
Installing rsync on Linux
Good news: rsync comes pre-installed on almost every major distro. Check if you already have it:
rsync --version
If it’s missing for some reason, install it with your package manager:
# Debian/Ubuntu
sudo apt install rsync
# RHEL/Fedora
sudo dnf install rsync
# Arch Linux
sudo pacman -S rsync
That’s it. No dependencies to wrangle, no config files to edit. Visit the rsync official project page if you want to build from source, but honestly, your distro’s package is the way to go.
Basic rsync Syntax
Every rsync command follows this pattern:
rsync [options] source destination
Simple enough. But there’s one detail that trips up almost everyone the first time.
Understanding the Trailing Slash (It Matters More Than You Think)
⚠ Watch the Trailing Slash
With trailing slash on source — copies the contents of the directory:
rsync -av /home/user/docs/ /backup/
Result: files land directly in /backup/
Without trailing slash — copies the directory itself:
rsync -av /home/user/docs /backup/
Result: creates /backup/docs/ containing the files
This is the single most common rsync mistake. I’ve seen it create nested directory messes in production. When in doubt, add --dry-run first and check what rsync plans to do.
Syncing Files Locally
Let’s start with the most common use case: syncing files between two directories on the same machine.
Copy a Single File
rsync -v /home/user/report.pdf /backup/report.pdf
The -v flag gives you verbose output so you can see what’s happening. For a single file, this works like a smarter cp.
Sync an Entire Directory with -a (Archive Mode)
The -a flag is the workhorse of rsync. It stands for “archive mode” and it’s actually a shortcut for seven flags combined: -rlptgoD.
In plain English, -a means:
- Recursive: Include all subdirectories
- Preserve symlinks, Linux file permissions, timestamps, group, and chownership
- Copy device and special files
💡 Pro Tip: Always Dry-Run First
Add --dry-run (or -n) to preview what rsync will do without changing anything:
rsync -av --dry-run /source/dir/ /dest/dir/
Once you’re happy with the output, remove --dry-run and run it for real.
Syncing Files Remotely Over SSH
This is where rsync really shines. It uses SSH by default for encrypted remote transfers. If you can SSH into a server, you can rsync to it. No extra setup needed. If you’re curious about what’s happening under the hood, our guide on SSH tunneling dives deeper into how these connections work.
Push Files to a Remote Server
rsync -avz /local/dir/ user@remote-server:/remote/dir/
The -z flag enables compression during transfer. Great for slow or metered connections, though it uses extra CPU. On a fast LAN, you can skip it.
Pull Files from a Remote Server
rsync -avz user@remote-server:/remote/dir/ /local/dir/
Same syntax, just swap source and destination. rsync doesn’t care which direction you’re going.
Want a progress bar and resume capability? Add -P:
rsync -avzP user@remote-server:/remote/dir/ /local/dir/
The -P flag combines --partial (resume interrupted transfers) and --progress (shows a progress bar). I keep it on for any transfer over a few hundred MB.
Set Up Passwordless SSH Keys for Automation
If you plan to automate rsync with cron (and you should), you need SSH keys that don’t require a password prompt:
# Generate a key pair (if you haven't already)
ssh-keygen -t ed25519
# Copy your public key to the remote server
ssh-copy-id user@remote-server
If your server runs SSH on a non-standard port, tell rsync about it:
rsync -avz -e 'ssh -p 2222' /src/ user@host:/dst/
The Most Useful rsync Options Explained
rsync has dozens of flags, but you’ll use these the most. For the full reference, check the rsync man page.
| Option | What It Does |
|---|---|
--delete |
Removes destination files not in source. Creates a true mirror. Use with caution. |
--exclude 'pattern' |
Skip files matching the pattern (e.g., --exclude '*.log') |
--exclude-from=FILE |
Read exclude patterns from a file, one per line |
--bwlimit=KBPS |
Throttle bandwidth (e.g., --bwlimit=5000 = ~5MB/s) |
-u (--update) |
Skip files newer on the destination |
--link-dest=DIR |
Incremental backups with hard links (Time Machine-style) |
-P |
Show progress + resume interrupted transfers |
The --bwlimit flag is one I wish I’d known about sooner. Early in my sysadmin days, I kicked off a massive rsync to a production server during business hours. Saturated the entire uplink. Tickets started pouring in. Now --bwlimit=5000 is muscle memory for any production transfer.
Red Hat recommends -avuP as a solid default for interactive use: archive mode, verbose output, skip newer files, and show progress with resume.
How to Automate rsync with Cron
Running rsync by hand is fine for one-off transfers. But the real power comes when you automate it. If you’re new to cron, check out our full guide on cron jobs in Linux first.
Here’s a cron entry that runs a nightly backup at 2 AM:
0 2 * * * /usr/bin/rsync -avz --delete /home/user/ user@backup-server:/backups/home/ >> /var/log/rsync-backup.log 2>&1
A few critical details:
- Use absolute paths. Cron doesn’t load your
$PATH, so/usr/bin/rsyncinstead of justrsync. - Set up SSH keys first. There’s no one to type a password at 2 AM. Without passwordless keys, cron jobs fail silently.
- Redirect output to a log file. The
>>appends output and2>&1captures errors too. Without logging, you’ll never know if something broke.
For more complex backup logic, consider wrapping your rsync commands in Bash scripts. You can add error checking, notifications, and rotation logic. You could also use a systemd service with timers as a modern alternative to cron.
Common rsync Mistakes (And How to Avoid Them)
I’ve made most of these myself. Learn from my pain.
- Forgetting the trailing slash. You end up with
/backup/docs/docs/docs/after a few runs. Always double-check your paths. - Using
--deletewithout--dry-runfirst. I learned this the hard way. I set up what I thought was a perfect backup cron job to my homelab NAS. Ran it for weeks. Then I cleaned up a directory locally. Next morning, rsync had dutifully mirrored that empty directory to my backup server. Two years of project files, gone from both locations. That was the day--dry-runbecame non-negotiable in my workflow. - Skipping
-zon slow connections. Compression costs CPU but saves bandwidth. On anything slower than a LAN, use it. - Not setting up SSH keys for cron. The job runs, hits a password prompt with nobody there, and silently fails. You think your backups are running. They’re not.
- Not logging cron output. Always add
>> /var/log/rsync.log 2>&1. Future you will thank present you when something breaks at 3 AM.
Wrapping Up: rsync Is the Sync Tool You’ll Use Forever
Once you learn how to use rsync in Linux, it becomes one of those tools that just stays in your toolkit permanently. Here’s your cheat sheet:
📋 Quick Reference
- Local sync:
rsync -av /source/ /dest/ - Remote sync:
rsync -avz /source/ user@host:/dest/ - With progress: Add
-P - Mirror (delete extras): Add
--delete - Always test first: Add
--dry-run
Pair rsync with cron or systemd timers, and you’ve got a reliable, automated backup system that runs forever without babysitting. It’s the same approach powering backups on the majority of Linux servers worldwide.
If you’re building out a broader backup strategy, our guide on automatic backups in Linux covers the bigger picture. Need to archive files before syncing? Check out the tar command for creating compressed archives. And if you haven’t already, setting up cron jobs in Linux is the natural next step to making your rsync workflow fully hands-off.
rsync has been solving the file sync problem since 1996, and nothing has come close to replacing it. Start with rsync -av, add flags as you need them, and always, always dry-run first.




