scp vs SFTP vs rsync: which one to use

Use scp for a quick one-off copy, sftp to browse a server or when only SFTP is allowed, and rsync to sync folders, resume large transfers, or send only what changed. All three run over SSH. Since OpenSSH 9.0, scp uses the SFTP protocol by default. rsync must be installed on both machines.

Updated . OpenSSH 10.3 client on macOS to OpenSSH 10.0 on Debian 13 in a throwaway container.

Side by side

scpsftprsync
Best forOne quick copyBrowsing, restricted accountsSyncing folders, large files
Needs on the serverSSH with the SFTP subsystem, or scp with -OSSH with the SFTP subsystemSSH and rsync installed
Sends only changesNoNoYes
ResumeNoYes, reget and reputYes, --partial
Port option-P 2222-P 2222-e 'ssh -p 2222'

scp

scp file.txt user@server:/tmp/
scp -r folder user@server:/tmp/
scp -P 2222 user@server:/var/log/app.log .

Since OpenSSH 9.0, scp uses the SFTP protocol and not the old scp protocol. You can see it with scp -v, which prints Sending subsystem: sftp. The practical gain is that file names with spaces or special characters no longer need double quoting.

If the server has no SFTP subsystem, the copy fails with subsystem request failed on channel 0. Add -O to use the old protocol:

scp -O file.txt user@server:/tmp/

More cases, such as folders, other ports and two servers, are in scp examples.

sftp

sftp user@server opens a small shell with ls, cd, get, put and bye. It works on accounts that have no shell, so it is the usual choice for restricted users. See the sftp-only user setup.

Every command at the prompt is in the list of sftp commands.

It can resume. Inside sftp, these continue a partial file:

reput big.bin /tmp/big.bin
reget /tmp/big.bin big.bin

In our test both finished from a partial file, and the checksums matched the original. For scripts, put the commands in a file and run sftp -b commands.txt user@server.

rsync

rsync -av src/ user@server:/srv/app/
rsync -avz -e 'ssh -p 2222' src/ user@server:/srv/app/
rsync -aP big.bin user@server:/tmp/

-a keeps permissions, times and links and copies folders. -v lists files. -z compresses, which helps with text on slow links. -P means --partial --progress.

rsync has to exist on both sides. Without it on the server you get:

bash: line 1: rsync: command not found

The trailing slash

A slash at the end of the source changes the result. We ran both forms on a folder src holding a.txt:

rsync -a src  user@server:/tmp/noslash/   # creates /tmp/noslash/src/a.txt
rsync -a src/ user@server:/tmp/slash/     # creates /tmp/slash/a.txt

With the slash, rsync copies the contents of the folder. Without it, it copies the folder itself. A slash on the destination makes no difference.

Sending only what changed

In our test, a 50 MiB file was sent once, then 4 KiB in the middle of it was changed:

  • First transfer: 52,441,699 bytes sent.
  • Second transfer: 43,547 bytes sent.

This saving happens across a network. Between two folders on one machine, rsync copied the whole file again in our test.

Resuming

We stopped a transfer of that file with --partial, which left 15.4 MB at the destination. Running the same command again reused those bytes and sent the rest, and cmp found the result identical to the original. Without --partial, rsync removes the partial file when it is interrupted.

Two traps

  • rsync may skip a changed file. By default it compares only size and modification time. In our first test the 4 KiB change landed within the same second as the earlier copy, with the same size, and rsync sent nothing. -c compares checksums, at the cost of reading every file.
  • --delete removes files at the destination that are not in the source. With a wrong path, that can be a lot of files. Add -n first to see the list: rsync -avn --delete src/ user@server:/srv/app/.

On recent macOS, /usr/bin/rsync may be openrsync and not the original: on our test Mac rsync --version printed openrsync: protocol version 29. The options above worked, but it does not have everything, so check the output of rsync --version if an option is refused.

Which to choose

  • One file, once: scp.
  • You need to look around first, or the account allows only SFTP: sftp.
  • The same folder again and again, or a large file on a bad connection: rsync.
  • Your local editor and tools on server files: mount the folder with sshfs.

All three read your SSH config, so a Host entry saves the port and user. See the SSH config file.

Questions

Is SFTP the same as scp?

No. sftp is an interactive client for browsing and transferring files, and scp is a one-line copy command. Since OpenSSH 9.0, scp uses the SFTP protocol underneath.

Is rsync faster than scp?

When the destination already has an older copy, yes: rsync sends only the changed parts. In our test, a 4 KiB change in a 50 MiB file sent about 43 KB. For a new file, both send the whole file.

Does rsync work over SSH?

Yes. For a remote path rsync connects with ssh by default, but rsync must also be installed on the server.

Sources

All guides