Skip to content

scp — Secure Copy Over SSH

scp — a utility for copying files over SSH using the SSH protocol. It works from the terminal, requires no extra server setup — just a running sshd and working authentication. In an era of rsync and bat, SCP survives as a simple tool for one-off transfers when you don’t want to deal with daemons or configuration files.

Syntax and Basic Scenarios

General form:

scp [flags] source destination

Source and destination can be local paths or remote addresses in the format user@host:path.

# Local file to a remote machine
scp ./deploy.tar.gz deploy@10.0.2.15:/opt/app/

# Remote file to the local machine
scp deploy@10.0.2.15:/opt/app/deploy.tar.gz ./

# Between two remote hosts (via the local machine)
scp user@host1:/data/backup.sql user@host2:/data/restore/
Tip

If the remote host uses a non-standard SSH port, specify it with -P (uppercase P — that’s how scp differs from ssh).

Recursive Directory Copying

To copy a directory, the -r flag is required. Without it, scp refuses to transfer a directory and prints an error.

scp -r ./project/ dev@10.0.2.15:/home/dev/projects/
Warning

When copying recursively, scp transfers the contents of the directory, not the directory itself. Behavior depends on whether the trailing / is present in the path — verify the result if the structure matters.

Useful Flags

FlagDescription
-rRecursive directory copying
-P portSSH port on the remote host
-pPreserves modification time, access, and file permissions
-qQuiet mode, no progress bar
-CCompression during transfer
-i key.pemSpecifies a private key
-o StrictHostKeyChecking=noAutomatically accepts new host keys
-l rateBandwidth limit in Kbit/s
scp -r -p -C -i ~/.ssh/deploy_key.pem -P 2222 ./build/ deploy@10.0.2.15:/var/www/

Typical Transfer Patterns

Deploying artifacts:

scp ./release.tar.gz deploy@prod:/tmp/releases/

Fetching a log from a remote server:

scp admin@10.0.2.15:/var/log/app/error.log ./logs/

Transferring multiple files at once:

scp config.yaml secrets.env deploy@10.0.2.15:/opt/app/

Direct transfer between two servers (both source and destination are remote):

scp -3 user@host1:/data/file.csv user@host2:/data/import/

The -3 flag routes traffic through the local machine. Without it, scp attempts a direct connection between the hosts, which usually fails.

Limitations and Alternatives

scp does not support resuming interrupted transfers — if the connection drops halfway through a multi-gigabyte file, you start over. There is no incremental sync, no checksum verification. Transfers are sequential, with no built-in parallel file transfer.

For everyday tasks, rsync solves these problems:

rsync -avz -e "ssh -p 2222" ./build/ deploy@10.0.2.15:/var/www/

rsync can resume broken transfers, skip already-copied files, and work incrementally. For one-off transfers of a few small files, scp remains convenient — fewer parameters, faster to type.

Note

On modern distributions, scp may be wrapped by the OpenSSH client. Behavior is the same, but if you notice differences in output or error handling, that’s normal — the implementation depends on the OpenSSH version.