rsync — sync files, local or remote

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.

What it does

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.

Why it matters

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.

Examples

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.

Flags

FlagMeaning
-aarchive mode: preserve mode, times, ownership, symlinks — the almost-always-right default
-vverbose; add a second -v (or -vv) for more detail
-zcompress data during transfer — great for text and slow links, pointless for already-compressed files
--deleteremove files on the destination that are absent on the source, for a true mirror
-ndry run: show what would happen without transferring anything. Always run -n before --delete
-especify the remote shell, e.g. -e 'ssh -p 2200' to use a non-default port
--partialkeep partially transferred files so a rerun resumes instead of restarting
-Pshorthand for --partial --progress: show progress bars and resume on interrupt

Origin

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.

The delta algorithm, distilled

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.

Fun facts

Pros

Cons

Takeaways