Basics

SFTP, SCP or rsync — picking the right one

6 min read

All three run over SSH. All three use the same keys, the same ~/.ssh/config, the same authentication. The difference is what happens once the connection is up, and it is enough of a difference that picking the wrong one wastes real time.

The short version: rsync for anything repeated or large, SFTP for browsing and interactive work, and scp mostly for muscle memory.

scp, and why it is on the way out

scp copies a file. That is the whole feature.

scp dump.sql prod:/tmp/
scp prod:/var/log/nginx/error.log ~/Desktop/

It is the fastest thing to type, which is why it is not going anywhere socially. Technically, though, the OpenSSH maintainers have been steering people away from it for years, and it is worth knowing why rather than treating it as fashion.

The original protocol was based on 1980s rcp and had a genuinely bad property: the server decides what gets written. The client asks for file.txt and trusts the server’s answer about what it is sending — so a malicious server could return different filenames and drop files elsewhere in your directory (CVE-2019-6111). Filename handling also went through a remote shell, which made quoting and glob expansion a recurring source of surprises and injection bugs.

What changed: OpenSSH 8.8 (2021) added an SFTP-backed mode, and OpenSSH 9.0 (2022) made it the default. On a current macOS, when you type scp you are already using the SFTP protocol underneath, with the old behaviour available only via -O. The old sharp edges are gone for most people, but the command still has no resume, no progress you can trust for a directory, and no way to see what is on the far side before you commit.

scp is fine for one small file when you know exactly what you want. For everything else there are better answers.

SFTP, the one built for browsing

SFTP is a real file transfer protocol running as a subsystem inside the SSH connection. It can do the things a file manager needs: list a directory, stat a file, rename, delete, chmod, create directories, resume an interrupted transfer, read part of a file.

sftp prod
sftp> cd /var/www/releases
sftp> ls -l
sftp> get -r current
sftp> put dist.tar.gz

The interactive client is serviceable and nobody enjoys it much, which is why SFTP is mostly used through a GUI. That is the actual use case: when you do not know in advance which file you want. Poking through /var/log looking for the one that grew, pulling a config to compare it, dropping a build into place and fixing its permissions afterwards.

Note that it is not “FTP over SSH”. FTP is a separate, older protocol, and FTPS is FTP wrapped in TLS. SFTP shares nothing with either beyond the three letters — it needs no extra port, no extra daemon, no extra credentials. If you have SSH, you already have SFTP.

rsync, when it is the only right answer

rsync compares source and destination and transfers only the differences.

rsync -avz --progress ./dist/ prod:/var/www/app/

For a first copy that is no better than anything else. For the second one, it is transformative: a 4 GB directory where one file changed transfers that one file. It also resumes properly (--partial), preserves permissions and timestamps (-a), compresses in flight (-z) and can mirror deletions (--delete, which deserves a --dry-run first, every time).

The trailing slash on the source is not decoration. ./dist/ copies the contents of dist into the target; ./dist copies the directory itself, producing /var/www/app/dist/. This catches everyone at least once.

The one requirement: rsync must be installed on both ends. Usually true on Linux, occasionally not on a minimal container or a BSD appliance, and that is the only real reason to reach for something else.

Because it runs over SSH, your config applies:

rsync -avz -e ssh ./dist/ prod:/var/www/app/

-e ssh is the default and rarely needs stating, but it is where you would put extra SSH options if you needed them.

Choosing

Use rsync for deployments, backups, anything you will run more than once, anything over a few hundred megabytes, and any transfer over a connection that might drop.

Use SFTP when you need to look before you copy, when you are working with permissions, or when a colleague who does not live in a terminal needs to move a file.

Use scp for one small file, one time, when typing speed is what matters.

Use none of them for structured data that has its own tool. pg_dump/psql and mysqldump piped over SSH beat dumping to a file, copying it, and importing it:

ssh prod 'pg_dump -Fc appdb' > appdb.dump

The thing about opening a second connection

Here is a detail that matters more than it sounds. When you are in an SSH session and want to move a file, running scp or sftp in another terminal opens a second, independent SSH connection. That means a second authentication: a second key challenge, and if the server uses 2FA, a second OTP prompt. It is also a second entry in the server’s auth log, which is noise if anyone reads those.

The SSH protocol does not require this. SFTP is a channel inside a connection, and a client that already has one open can start an SFTP subsystem on it rather than dialling again.

That is what Upshell does: the file browser runs on the same connection as the shell you are already in. One login, and you can browse, transfer, and change permissions while the shell sits there with your command history intact. Files can be dragged straight to the Finder and previewed with Quick Look. Most clients open a second session; the difference is one authentication instead of two every time you touch a file — which, if your servers are behind 2FA, is the difference between using the feature and avoiding it.

Step by step

  1. Decide whether you will do this again. If yes, rsync. Setting it up once is cheaper than the second manual copy.
  2. Decide whether you know the filename. If not, you want SFTP and a browser, not a copy command.
  3. Check rsync is on the serverssh prod 'command -v rsync'. If it is missing and you cannot install it, fall back to SFTP.
  4. Dry-run anything with --deletersync -avn --delete ./dist/ prod:/var/www/app/. The -n costs a second and has saved a great many directories.
  5. Mind the trailing slash./dist/ copies the contents, ./dist copies the directory. Confirm with the dry run.

Questions people ask

Is scp deprecated?

Not removed, but no longer recommended. Since OpenSSH 9.0 it runs over the SFTP protocol by default, which fixed its worst security properties. It still lacks resume, directory progress and any way to inspect the remote side, so rsync or SFTP is the better answer for most work.

Is SFTP the same as FTP over SSH?

No. FTP is an unrelated, older protocol, and FTPS is FTP wrapped in TLS. SFTP is a subsystem of SSH — same port, same keys, same authentication, nothing shared with FTP but the letters.

Which is fastest?

For a single first-time transfer, all three are close and the network is the limit. For anything repeated, rsync wins by a margin that grows with how little has changed — it can turn a ten-minute transfer into two seconds.

Can I use rsync through a bastion?

Yes. rsync uses your SSH configuration, so a host with ProxyJump in ~/.ssh/config works unchanged: rsync -avz ./dist/ app-prod:/var/www/.

Upshell — the native SSH & SFTP client for macOS

Tabbed and split terminal, saved hosts with keys and 2FA, multi-hop bastions, port forwarding and SFTP on the very same connection. Free to download, no subscription required.