rsync network
omfg you're just copying files.
The rsync man page is 4,800 lines long. You need about six of them.
You Googled “how to transfer files to remote server.” You clicked the first StackOverflow link. Someone said “just use FileZilla.” You downloaded it. You installed it. You clicked through three dialog boxes. You set up a “site profile.” You typed the hostname wrong. You fixed it. You saved the profile so you’d never have to type it again — except you forgot what you named it two weeks later. You dragged files between two panels like you’re playing Minesweeper. You felt productive.
Meanwhile, rsync has been sitting on your machine since the day you installed the OS. Waiting. Quietly judging you.
Unless you’re running Windows — then what the hell are you doing here anyways?! If you want to join the party and understand what the hell we’re talking about, go install WSL2. We’ll wait. Impatiently.
Lazy sysadmins can skip straight to the cheat sheet.
Copy files from here to there
Local to local. The thing you keep opening a file manager for. The thing where you have two Explorer windows side by side, carefully dragging files between them, praying you don’t accidentally drop them into the wrong subfolder and spend twenty minutes figuring out where they went.
rsync -av /source/folder/ /destination/folder/
That trailing slash matters. Think of it like boxes:
/source/folder/(with slash) — pour the contents of the box into the destination box/source/folder(no slash) — put the entire box inside the destination box
# With slash: contents land directly in /backup/
rsync -av /source/photos/ /backup/
# Result: /backup/file1.jpg, /backup/file2.jpg
# Without slash: the folder is recreated inside /backup/
rsync -av /source/photos /backup/
# Result: /backup/photos/file1.jpg, /backup/photos/file2.jpg
Get this wrong and you end up with /backup/photos/photos/ nested inside itself, questioning every decision that led you to this moment.
Copy files to another machine
The thing you installed FileZilla for. The thing that somehow requires a 47MB application with a toolbar, a quickconnect bar, a message log panel, and a “transfer queue” — to copy a file.
rsync -avz -e ssh /local/folder/ user@remote:/remote/folder/
That’s it. That’s the whole thing. One line. No toolbar. No quickconnect bar. No “transfer queue.” -z compresses in transit because you’re not an animal.
Copy files FROM another machine
FileZilla’s other panel. The one you keep accidentally clicking.
rsync -avz -e ssh user@remote:/remote/folder/ /local/folder/
Same thing, reversed. Notice how you didn’t need a GUI with two panes, sixteen icons, and a status bar that says “Idle” for this.
Only copy what changed
This is where rsync makes every GUI drag-and-drop tool look like a children’s toy. It checksums files and only transfers the differences. Not the whole file. The differences. Your GUI tool copied the entire 2GB folder again because you changed one config file. rsync sent 4KB. Sleep on that.
rsync -avz --progress /source/ /destination/
--progress shows you what’s happening because staring at a silent terminal builds character, but not today.
Dry run first
Not sure what’s going to happen? You know what FileZilla’s dry run feature is? It doesn’t have one. It just does things and hopes for the best. Like you, apparently.
rsync -avzn /source/ /destination/
-n means dry run. It shows you what would happen without touching anything. Use this. Your future self is begging you.
Exclude stuff you don’t want
rsync -avz --exclude='node_modules' --exclude='.git' /source/ /destination/
Or use a file, because you’re not going to type --exclude fourteen times like a psychopath:
rsync -avz --exclude-from='exclude-list.txt' /source/ /destination/
One pattern per line. Just like .gitignore but without the existential crisis about whether the pattern is right.
Delete files at destination that don’t exist at source
A true mirror. This is dangerous and beautiful.
rsync -avz --delete /source/ /destination/
This makes the destination an exact copy. Files that exist at the destination but not the source get nuked. Combine with -n first unless you enjoy explaining to your boss what happened to the production assets.
Custom SSH port
Your server runs SSH on port 2222 because your sysadmin read a blog post about security through obscurity. Fine. Here’s how you deal with that:
rsync -avz -e 'ssh -p 2222' /local/ user@host:/remote/
Note the quotes around ssh -p 2222. Forget them and enjoy a cryptic error message that tells you absolutely nothing useful.
Limit bandwidth
Syncing 200GB to a remote server? Your coworkers would love to keep using the internet today.
rsync -avz --bwlimit=5000 /src/ /dest/
That’s 5,000 KB/s (roughly 5 MB/s). Adjust to whatever won’t get you a Slack message from the network team asking “what the hell is happening to the bandwidth.”
Show transfer stats
Want to know how much time rsync just saved you compared to dragging files like a caveperson?
rsync -avz --stats /src/ /dest/
It’ll show you bytes sent, bytes received, and a “speedup” ratio. That ratio is how much faster rsync was than copying everything from scratch. Screenshot it. Send it to the person who recommended FileZilla.
The flags that actually matter
| Flag | What it does |
|---|---|
-a |
Archive mode. Preserves permissions, timestamps, symlinks — the works. You always want this. |
-v |
Verbose. Shows what’s being transferred. |
-z |
Compress during transfer. Use for remote copies. Skip for local copies unless you enjoy wasting CPU cycles. |
-n |
Dry run. Shows what would happen. Use this before --delete or update your résumé first. |
-P |
Shows progress AND keeps partial transfers. Same as --progress --partial. |
--delete |
Remove files at destination not present at source. Read the previous sentence again. |
-e ssh |
Transfer over SSH. Which is how you should always do it. If you’re not using SSH, we need to have a different conversation. |
-e 'ssh -p PORT' |
SSH on a non-standard port. Don’t forget the quotes. |
--bwlimit=KB |
Cap transfer speed in KB/s. Be a good network citizen. |
--stats |
Show transfer summary. Proof that rsync is better than whatever you were using. |
“But I need a GUI to manage my—”
No you don’t.
“I need to save connection profiles.” That’s an SSH config file. Three lines in ~/.ssh/config and you never type a hostname again. FileZilla made you set up a “site manager” with a username field, a password field, a port field, and a dropdown for the protocol. You know what an SSH config entry looks like? This:
Host myserver
HostName 192.168.1.50
User admin
That’s it. Now rsync -avz -e ssh files/ myserver:/path/ works forever. No profile. No dropdown. No “did you save?”
“I need to see a progress bar.” --progress. Or -P. One flag. Not a 47MB download with a built-in progress panel.
“I need to schedule transfers.” That’s cron. One line. Your GUI app wants you to pay for the “Pro” version to schedule transfers. Let that sink in.
“FileZilla lets me browse directories.” So does ls. And ls has never asked you to install an update, popped up a donation nag, or quietly bundled adware in the installer. Yeah. That happened.
Cheat sheet
You made it. Or you skipped straight here. Either way, no judgment. Copy and paste these. Pin them. Tattoo them on your forearm. Whatever works.
| What you’re doing | Command |
|---|---|
| Copy local files | rsync -av /src/ /dest/ |
| Copy to remote machine | rsync -avz -e ssh /local/ user@host:/remote/ |
| Copy from remote machine | rsync -avz -e ssh user@host:/remote/ /local/ |
| Only copy what changed | rsync -avz --progress /src/ /dest/ |
| Dry run (see what would happen) | rsync -avzn /src/ /dest/ |
| Exclude files/folders | rsync -avz --exclude='node_modules' /src/ /dest/ |
| Mirror (delete extras at dest) | rsync -avz --delete /src/ /dest/ |
| Custom SSH port | rsync -avz -e 'ssh -p 2222' /local/ user@host:/remote/ |
| Limit bandwidth (5 MB/s) | rsync -avz --bwlimit=5000 /src/ /dest/ |
| Show transfer stats | rsync -avz --stats /src/ /dest/ |
Trailing slash reminder:
/folder/copies contents./foldercopies the folder itself. This will bite you exactly once.