Only send the bytes that changed. Resume, verify, mirror — without the resend.
scp re-downloads the whole file every time. rsync figures out which 2 KB changed out of 4 GB and moves only that. Once you feel the speed of a second sync, plain scp stops making sense.
rsync copies files between locations — local-to-local, local-to-remote via ssh, or remote-to-local — but it only transfers the parts that actually differ. It splits each file into chunks, hashes them, and sends only the changed chunks to the other side. That delta algorithm is what makes rsync the tool of choice for backups, mirroring, and deploying to servers: the second run over an unchanged tree finishes in seconds instead of re-copying gigabytes. It also preserves permissions, ownership, timestamps, symlinks, and hardlinks when you ask, and it can delete files on the destination that no longer exist on the source for a true mirror.
Every deployment and every backup is really a sync: you want the destination to match a source you keep changing. cp and scp don't do delta — they copy everything every time. rsync's incremental transfer is the difference between a 40-second deploy and a 2-second one, and the reason cron-driven rsync backups can run nightly without hammering bandwidth. The killer feature is that it's resumable and safe: if it dies halfway over a flaky connection, rerunning it picks up where it left off instead of starting over.
rsync -av --delete src/ backup/
sending incremental file list ./ index.html app.js styles.css sent 1,234,567 bytes received 45 bytes 617,306.00 bytes/sec total size is 3,456,789 speedup is 2.80 $ echo new > src/index.html $ rsync -av --delete src/ backup/ sending incremental file list index.html sent 21 bytes received 38 bytes 118.00 bytes/sec total size is 3,456,789 speedup is 163,657.00
-a archives (preserves mode, times, ownership, symlinks), -v is verbose, --delete removes files in backup/ that no longer exist in src/. Run it twice: only the one changed file re-transfers, and the speedup explodes.
rsync -avz -e 'ssh -p 2200' ./dist/ deploy@server:/var/www/app/
sending incremental file list ./ assets/app.8f3a2c.js assets/vendor.77b1d9.css index.html sent 1,890,432 bytes received 6,912 bytes 126,423.00 bytes/sec total size is 5,012,987 speedup is 2.65
-z compresses during transfer (big win for text over WAN), and -e lets you pass a custom ssh command — here a non-default port. This is the canonical "ship a build to a server" pattern.
rsync --partial --append-verify -av data.bin server:/backups/data.bin
sending incremental file list large-file-2026-09-14.bin sent 3,845,621,504 bytes received 32 bytes 12,481,889.00 bytes/sec total size is 4,294,967,296 speedup is 1.12 # connection died at 89%, rerun: $ rsync --partial --append-verify -av data.bin server:/backups/data.bin sending incremental file list large-file-2026-09-14.bin 3,845,621,504 89% 25.1MB/s 0:00:18 sent 449,345,792 bytes received 40 bytes 21,987,000.00 bytes/sec sent 449,345,792 bytes received 40 bytes 21,987,000.00 bytes/sec total size is 4,294,967,296 speedup is 9.56
--partial keeps the bytes already sent instead of discarding them on interrupt, and --append-verify resumes from where it stopped then verifies the tail. Combined, a dropped connection costs you only the unsent remainder.
| Flag | Meaning |
|---|---|
-a | archive mode: preserve mode, times, ownership, symlinks — the almost-always-right default |
-v | verbose; add a second -v (or -vv) for more detail |
-z | compress data during transfer — great for text and slow links, pointless for already-compressed files |
--delete | remove files on the destination that are absent on the source, for a true mirror |
-n | dry run: show what would happen without transferring anything. Always run -n before --delete |
-e | specify the remote shell, e.g. -e 'ssh -p 2200' to use a non-default port |
--partial | keep partially transferred files so a rerun resumes instead of restarting |
-P | shorthand for --partial --progress: show progress bars and resume on interrupt |
rsync was created in 1996 by Australian developer Andrew Tridgell (the same man who later wrote Samba). The core insight came from a paper by Andrew Tridgell (no relation) and Paul Mackerras on efficient file transfer using hashes. rsync's delta algorithm — split a file into variable-length blocks, hash each block on both ends, and send only the blocks that differ — grew directly out of that research. It spread so fast that within a couple of years it was the default way people mirrored sites and took backups.
Here is the trick that made rsync famous. Say a 4 GB file sits on both machines. The sending end checksums that file locally, then asks the receiver for checksums of the same file. By comparing rolling checksums, rsync finds the few chunks that differ and transfers only those — often a handful of kilobytes. It doesn't need the whole file on either side, and it doesn't need the two files to be identical in length. This is why the first sync is slow and every sync after it is shockingly fast.