Skip to content
DevOps devops networking 5 min read

Transferring Files (scp & rsync)

Sooner or later you will need to move files between your laptop and a server: pushing a website you built, pulling down a log file, or deploying a whole folder. Both scp and rsync do this over SSH (Secure Shell — the encrypted protocol you already use to log into servers), so your files travel safely across the network. The difference is how they copy: scp blindly copies everything every time, while rsync is smart and only sends the parts that changed. This page shows you both, and explains exactly when each one is the right tool.

What scp is and when to use it

scp stands for “secure copy”. It copies files from one machine to another over an SSH connection. It is built into the OpenSSH client, so if you can ssh into a server, you already have scp.

scp is best for one-off, simple copies: a single file or a small folder you just need to get from A to B once. It has almost no options to learn, which makes it quick for quick jobs.

Note: On modern Ubuntu (22.04 / 24.04 LTS), scp uses the SFTP protocol under the hood by default instead of the old legacy scp protocol. The commands below are unchanged, but transfers are safer and more reliable than they were on older systems.

Copying a file to a server

The pattern is always scp SOURCE DESTINATION. A remote location is written as user@host:/path.

scp ./report.pdf [email protected]:/home/deploy/uploads/

Output:

report.pdf                              100%  2048KB   4.1MB/s   00:00

Copying a file from a server to your machine

Just swap the order. The remote side is the source, and . means “my current directory”.

scp [email protected]:/var/log/nginx/error.log .

Output:

error.log                               100%   18KB  120.4KB/s   00:00

Copying a whole folder

By default scp refuses to copy directories. Add -r (recursive) to include everything inside.

scp -r ./mysite [email protected]:/var/www/

If your server uses a non-standard SSH port, note that scp uses a capital -P for the port (regular ssh uses lowercase -p):

scp -P 2222 ./report.pdf [email protected]:/home/deploy/

What rsync is and when to use it

rsync (“remote sync”) also copies files over SSH, but it was designed for repeated transfers. The first time you run it, it copies everything. Every time after that, it compares the source and destination and sends only the differences — new files, changed files, and even just the changed bytes inside a large file. This is called delta transfer.

Install it on Ubuntu if it is not already present (it usually is):

sudo apt update
sudo apt install rsync

Use rsync when you will sync the same folder more than once, when you are deploying a website or app, when the files are large, or when your connection is slow or flaky and you need to be able to resume.

The flags you will use 90% of the time

The classic combination is -avz:

FlagMeaningWhy you want it
-aArchive modeCopies recursively and preserves permissions, timestamps, and symlinks
-vVerbosePrints each file as it transfers so you can see progress
-zCompressSqueezes data during transfer — faster over slow networks
--deleteMirrorDeletes files on the destination that no longer exist in the source
--dry-runPreviewShows what would happen without changing anything
--progressPer-file barShows a live progress bar for each file

Deploying a folder to a server with rsync

Say you built a static website in a local folder called dist/ and want to push it to /var/www/mysite/ on your server.

rsync -avz --progress ./dist/ [email protected]:/var/www/mysite/

Output:

sending incremental file list
index.html
assets/app.css
assets/app.js

sent 41,204 bytes  received 92 bytes  27,530.67 bytes/sec
total size is 38,901  speedup is 0.94

Gotcha: the trailing slash on the source matters. ./dist/ (with a slash) copies the contents of dist into the target. ./dist (no slash) copies the dist folder itself, creating /var/www/mysite/dist/. When in doubt, run with --dry-run first.

Run the exact same command again later, after you change one file, and rsync only sends that one file:

rsync -avz --progress ./dist/ [email protected]:/var/www/mysite/

Output:

sending incremental file list
index.html

sent 1,182 bytes  received 38 bytes  2,440.00 bytes/sec
total size is 38,920  speedup is 31.90

Making the destination an exact mirror

If you deleted some old files locally and want the server to match exactly, add --delete. Without it, deleted files linger on the server forever.

rsync -avz --delete ./dist/ [email protected]:/var/www/mysite/

Warning: --delete permanently removes files on the destination. Always run it once with --dry-run added so you can see what will be deleted before it actually happens.

Using a custom SSH port or key

rsync lets you pass any SSH option through the -e flag:

rsync -avz -e "ssh -p 2222 -i ~/.ssh/deploy_key" ./dist/ [email protected]:/var/www/mysite/

Resuming a big interrupted transfer

If a large transfer drops, add --partial so rsync keeps the half-copied file and continues from where it stopped next time, instead of starting over.

rsync -avz --partial --progress ./backup.tar.gz [email protected]:/home/deploy/

scp vs rsync — when to use which

SituationBest toolWhy
Copy one file, oncescpShortest command, nothing to learn
Deploy a website or app folderrsyncSends only changes, much faster on repeat
Re-sync the same folder regularlyrsyncDelta transfer skips unchanged files
Large files over a slow linkrsyncCompression plus resumable --partial
Need an exact mirror (remove stale files)rsync --deletescp cannot delete extra files
Server only has SSH, nothing extra installedscpAlways present with OpenSSH

The short rule: first copy, do it once — reach for scp. Copy it again and again — reach for rsync.

Best Practices

  • Always test risky rsync runs with --dry-run first, especially anything using --delete.
  • Use SSH keys instead of passwords for transfers (see SSH key authentication) so scripts and deploys run without prompts.
  • Mind the trailing slash on rsync sources — it changes whether you copy a folder or its contents.
  • Prefer rsync -avz for any deploy: archive mode preserves permissions and timestamps that a plain copy can mangle.
  • Never transfer secrets (like .env files or private keys) into a publicly served folder such as /var/www.
  • For large or unreliable transfers, add --partial --progress so you can resume and watch progress.
  • Combine rsync with a non-standard SSH port using -e "ssh -p PORT" rather than guessing — it must match your server’s SSH config.
Last updated June 15, 2026
Was this helpful?