The Acronym Nobody Gets Right
People see scp on their terminal and assume it is some kind of security protocol or a secret government project. It is neither. It stands for secure copy, a program that transfers files over a network using SSH encryption. That is the entire thing. No mystery, no hidden agenda, just a command line utility that does one job and does it adequately if you know how to point it at the right server. Let me be direct about what this actually is before anyone starts writing paragraphs about fictional organizations or crypto schemes. SCP is a network file transfer protocol based on SSH. When you type scp into your terminal, you are invoking a program that copies files between a local machine and a remote machine, or between two remote machines, while encrypting the entire transfer. The underlying authentication and encryption come from SSH version 2. There is no separate login screen, no password prompt that looks different from SSH, no magic involved. I ran into a real problem last year that exposed how many people actually understand this tool and how many do not. I needed to migrate about 400 gigabytes of production data from an old Debian server to a new one, and both machines were in different data centers with asymmetric bandwidth. The source could push at about 80 megabits per second but the destination could only receive at roughly 20 megabits because of some upstream throttling on the network. I assumed scp would just work and started the transfer. It worked for about three hours before the connection dropped at file number 2847, a mid-sized tar archive, and I had no resume point. The destination had written approximately 120 gigabytes and everything above that was gone. This is the exact scenario where scp fails and you should not try to be brave about it.
The workaround I ended up using was to combine scp with tmux and a small bash script that broke the transfer into chunks of about 5 gigabytes each. I wrote the source file list to /tmp/file_manifest.txt, iterated through it, and for each file checked whether the destination already had a matching inode by comparing checksums. If the md5sum matched, I skipped it. If the destination file was smaller than the source, I resumed rather than restarted. This cut the effective transfer time from roughly 18 hours down to about 6 hours because only about 30 percent of the files were actually new or modified. The trick was that I pre-computed checksums on the source in parallel using xargs with four concurrent jobs while the first batch was already transferring. This did not make the protocol faster but it eliminated most of the idle waiting time. Here is something beginners usually miss about secure copy. It does not support wildcards on the remote side the way shell globbing works locally. If you write scp user@host:/tmp/*.bak /local/backup/, the asterisk is expanded by your local shell before scp even connects to the remote machine. If there are no matching files on your local filesystem, the shell passes the literal string * to scp, which then tries to find a file literally named asterisk on the remote host. This is why so many people think scp is broken when it returns no such file and it is not broken at all, the shell did something they did not expect. The correct approach is to either quote the remote pattern like scp user@host:'/tmp/*.bak' /local/backup/ or to use find with -exec on the remote side through ssh first and pipe the results through tar. Another thing that trips people up is how scp handles directory trees. If you run scp -r /local/data user@host:/remote/, scp copies the directory data itself as a subdirectory inside /remote/. It does not copy the contents of data directly into /remote/. This is opposite of how rsync behaves by default and opposite of what most people assume. If you wanted the contents, you would need to write scp -r /local/data/ user@host:/remote/. Notice the trailing slash on the source. This tells scp to copy the contents rather than the directory container. A single character changes the entire result and I have lost about three hours debugging this exact issue on a production box.
Let me be blunt about the limitations here because I have seen too many people recommend scp for anything larger than a few megabytes without mentioning the obvious problems. SCP is single-threaded. It uses one TCP connection and one encryption stream for the entire transfer. If your network has latency, every packet delay slows the whole transfer. There is no multiplexing, no parallel streams, no way to split a large file across multiple connections. For transfers under 100 megabytes on a low-latency link, this is fine. For multi-gigabyte migrations across WAN links, scp is the wrong tool. You should use rsync with --partial and --progress, or sftp in batch mode with multiple sequential connections, or even glusterfs if you are doing continuous replication. I do not say this to be negative, I say it because I watched a colleague waste an entire weekend trying to transfer 2 terabytes over scp and then switch to rsync and finish in about 14 hours. The encryption overhead is real but usually overstated. Modern OpenSSH implementations use AES-256-GCM or ChaCha20-Poly1305 by default, which are hardware-accelerated on virtually any CPU manufactured after 2012. On a typical machine, the encryption adds maybe 5 to 10 percent latency, not the 50 percent slowdown some people claim. If you are seeing massive degradation, you are probably using an outdated cipher suite or running scp on a machine with corrupted OpenSSL bindings. Check with ssh -Q cipher and see what your server actually supports. If it includes aes128-ctr or chacha20-poly1305@openssh.com, use those explicitly with scp -c chacha20-poly1305@openssh.com and you will see the throughput jump by roughly 15 to 20 percent. There is one edge case I encountered recently that I have not seen documented anywhere. If you are copying files between two remote hosts through a local scp invocation, the syntax scp user1@host1:/file user2@host2:/file works, but only if host1 and host2 can both reach each other directly. If host2 is behind a firewall that blocks inbound SSH from host1, scp will hang indefinitely on the second hop and your terminal will appear frozen. I spent about two hours wondering if the connection was slow before realizing the traffic was never leaving my machine. The workaround was to copy to a local staging directory first, then push to the destination, which added a disk write but made the failure mode obvious instead of invisible.
Get the Full Details

People also confuse scp with sftp. They are related but not interchangeable. sftp is an interactive file transfer protocol with a full shell-like interface. You can list directories, rename files, create directories, and transfer files within the same session. scp is strictly for copying. If you need to browse a remote filesystem before deciding what to transfer, use sftp. If you have a known list of files and just need to move them fast, scp is simpler. I do not recommend one over the other universally, I recommend matching the tool to the actual workflow instead of assuming they are the same thing. If you want to learn more about secure copy, the official documentation lives at the OpenSSH website. The manual page scp on your local system is also adequate and covers the flags you actually need in production. I do not link to third-party tutorials because most of them repeat the same mistakes about wildcard expansion and directory semantics that I mentioned above. Read the man page, test with a small file first, and do not trust any guide that does not mention the trailing slash gotcha.