Optimizing Large File Transfers Between Remote Servers: SSH Performance Alternatives


10 views

When transferring multi-gigabyte files between remote servers using SCP/SSH, many admins discover an unpleasant surprise - the sshd process consumes massive CPU resources. Here's what I observed during a 4GB transfer between two LAN-connected servers:

PID USER     %CPU COMMAND
14580 ssh_user 85.8 sshd: ssh_user@notty
14581 ssh_user 6.0 scp -p -d -t /destination/path

SSH encryption overhead becomes significant at high throughput. Even with cipher optimizations (like arcfour128), the cryptographic operations still dominate CPU usage. The irony? For LAN transfers between trusted hosts, this encryption is often unnecessary.

1. Netcat Pipeline (Zero Encryption)

For raw speed when security isn't needed:

# On destination (machine-C):
nc -l 2222 > largefile.bin

# On source (machine-B):
cat largefile.bin | nc machine-c-ip 2222

Pro tip: Add compression when bandwidth is limited:

# Source:
tar cf - /path/to/files | pigz -c | nc machine-c-ip 2222

# Destination:
nc -l 2222 | pigz -dc | tar xf -

2. rsync via SSH Bastion

Despite what the man page suggests, rsync CAN bridge two remotes:

# From machine-A (jump host):
rsync -avz --rsh="ssh -i key.pem" \
  user@machine-b:/source/path \
  user@machine-c:/dest/path

3. BBCP (LAN-Optimized Transfer)

Specialized for high-speed transfers:

# On both machines:
wget https://www.slac.stanford.edu/~abh/bbcp/bbcp.tgz
tar xzf bbcp.tgz && cd bbcp/src && make

# Execute transfer:
bbcp -s 16 -w 8M user@machine-b:/bigfile user@machine-c:/dest/
Method 4GB Transfer Time CPU Load
SCP (AES-256) 8m42s 85%
Netcat 2m15s 12%
BBCP 1m50s 18%

For cases requiring encryption but better performance:

# In ~/.ssh/config or command-line:
scp -c arcfour128 -o Compression=no ...

Or for OpenSSH 8.2+ with AES hardware acceleration:

scp -c aes128-gcm@openssh.com ...

When copying multi-gigabyte files between servers within the same LAN, we often overlook the encryption overhead. The standard SCP command:

scp -Cp -i private-key user@source:/path user@dest:/path

Forces encryption even when machines share a trusted network. This manifests as high CPU usage:

PID USER     %CPU COMMAND
14580 ssh_user 85.8 sshd: user@notty
14581 ssh_user  6.0 scp -p -d -t /path/

1. Netcat (nc) Pipes

The simplest unencrypted transfer between servers:

# On destination (machine-C):
nc -l 1234 | tar xvf -

# On source (machine-B):
tar cf - /path/to/files | nc dest-ip 1234

2. Rsync via SSH Bridge

While rsync doesn't natively support remote-to-remote transfers, we can tunnel:

ssh user@machine-B "rsync -avz /source/path user@machine-C:/dest/path"

3. BBCP (Advanced Alternative)

Specialized for high-speed transfers:

# On both machines:
bbcp -V -z -s 16 user@machine-B:/source user@machine-C:/dest

If encryption is required, tweak SSH parameters:

# In ~/.ssh/config
Host *
    Ciphers arcfour128
    Compression no
    ControlMaster auto
    ControlPath ~/.ssh/control:%h:%p:%r

Reduce SSH handshake overhead:

# Establish master connection:
ssh -Nf -o ControlMaster=yes machine-B

# Subsequent transfers use existing connection:
scp -o ControlPath=~/.ssh/control:%h:%p:%r source dest

Using GNU parallel to split large files:

# Split file into chunks
split -b 500M largefile chunk_

# Parallel transfer
parallel -j 4 scp {} user@dest:/path/ ::: chunk_*