■ the answer first

rsync for backups, big trees, anything you will run more than once — scp for one small file, once.

scp cannot resume: a drop at 900 MB of 1 GB — 100 MB short — restarts from zero. rsync with --partial --append-verify turns that restart into a pause.

On re-runs rsync moves only the changed blocks; scp re-sends everything. The one flag to take away: --partial.

THE ONE LINE, ANNOTATED

Most people only ever need this — every flag labelled, in order:

the trailing slash trips everyone once — rsync even warns "no bytes transferred" when you meant the other form

WHAT THE STATE DIFFERENCE BUYS

scp does one thing: open an SSH channel, stream the bytes, close. No state between runs, so a transfer that dies at 90% restarts from zero and re-sends the whole 1,000 MB. rsync is a synchronisation tool that happens to use SSH as transport: before sending it builds a checksum list of the destination (the rolling-checksum delta algorithm) and transmits only the blocks that differ. Run the same command twice and the second pass moves almost nothing — which also makes rsync the natural tool for keeping two directories in sync: schedule it and each run copies just the deltas. The practical consequences:

IS RSYNC FASTER?

For a first-time copy of one large file over a fast link, they are close — both saturate SSH, and the checksum pass adds only a small overhead. The gap opens in three places:

  1. Small files in bulk. rsync pipelines directory walks and can reuse one connection; older scp setups spawned work per file. Thousands of little files — a node_modules, a WordPress install — finish noticeably faster with rsync.
  2. Re-runs. Copy a 4.0 GB file where 50 MB changed and rsync moves roughly 50 MB; scp moves 4 GB again.
  3. Compression. -z compresses in flight, which helps on slow WAN links.

You can time both yourself — the command is identical in shape, and the re-run is where the answer lives:

# same file, same server, both over SSH
time scp bigfile.tar.gz user@server:/tmp/
time rsync -avh --progress bigfile.tar.gz user@server:/tmp/

# re-run both: scp re-copies, rsync verifies and sends ~nothing
time scp bigfile.tar.gz user@server:/tmp/
time rsync -avh --progress bigfile.tar.gz user@server:/tmp/

THE RESUME INCANTATION

No, scp cannot resume an interrupted transfer — no flag, no trick. rsync's whole design assumes the transfer will be interrupted sometimes:

rsync -avh --partial --append-verify --progress bigfile.tar.gz user@server:/srv/backup/

Wrapped in a retry loop, this is a set-and-forget backup over even a hostile connection:

until rsync -avh --partial --append-verify --progress \
    ./bigfile.tar.gz user@server:/srv/backup/; do
  sleep 5
done

verify: run the same rsync again → it verifies and sends ~nothing

WHEN scp STILL WINS

One subtlety worth knowing: the OpenSSH project deprecated scp's original protocol years ago, and modern scp actually speaks SFTP underneath. That fixed a path-escaping quirk, but it changed nothing about the two limitations that matter — no resume, no delta transfer. The protocol change does not make scp rsync. And if your question is really "rsync vs cp": cp is the local-only equivalent of scp — no resume, no delta, no attributes unless you add flags — and for local one-shots it is fine.

THE DANGEROUS ONE

--delete mirrors deletions too — it removes files at the destination that are gone at the source. Powerful for mirrors, dangerous everywhere else. Dry-run anything that carries it:

rsync -avh --delete --dry-run src/ user@server:/srv/dest/   # review
rsync -avh --delete src/ user@server:/srv/dest/             # then commit

verify: the --dry-run pass prints the deletion list and changes nothing

For a daily or weekly sync, drop rsync into a systemd timer and let it copy only the deltas — the journal is where the runs leave their story.

THE VERDICT TABLE

scprsync
Ships with OpenSSHYesYes (both ends needed)
Resume interrupted transferNoYes (--partial)
Delta transfer on re-runsNoYes
Preserve permissions/symlinksPartiallyFully (-a)
Exclude patternsNo--exclude
Dry runNo--dry-run
Mirror deletionsNo--delete
Best forQuick one-off copiesBackups, syncs, bulk trees

Default to rsync for backups, big trees, anything over a link that can drop, and anything you will run more than once. Use scp when the command is shorter than the thought. If you take one flag away, take --partial — it converts every future dropped connection from a restart into a pause.

■ honest stamp Tested on: rsync · scp (speaks SFTP underneath) · your existing SSH keys and config. First published 2026-09-08, record refreshed 2026-10-04. Every command runs as printed; the resume behaviour, the delta algorithm and the SFTP switch are rsync's and OpenSSH's documented behaviour, typed from transfers that actually dropped.

end of the copy page · nothing fetched · everything local