qcp: Faster File Transfers Over High-Latency Networks Using QUIC

If you've ever tried to scp a large file across continents, you know the pain. TCP's congestion control wasn't designed for high-latency links, and throughput often crawls even when bandwidth is available. Enter qcp, a drop-in replacement for scp that uses the QUIC protocol to maximize throughput on challenging network paths.
What Is qcp?
qcp (QUIC Copier) is a file transfer utility written in Rust that tunnels file data over QUIC instead of TCP. It uses SSH for authentication (just like scp), then establishes a QUIC session for the actual data transfer.
Key features:
- Drop-in replacement for
scp(same syntax) - Uses SSH for authentication (no new credentials needed)
- QUIC-based transfer for better performance on congested/high-RTT links
- Supports multiple files and recursive directory copies
- Cross-platform: Linux, macOS, Windows, FreeBSD
Why QUIC Beats TCP for Long-Distance Transfers
TCP was designed in an era of low-latency, low-loss networks. On modern internet paths with 100ms+ round-trip times, TCP's congestion control becomes overly conservative:
| Factor | TCP (scp) | QUIC (qcp) |
|---|---|---|
| Connection setup | 3-way handshake + TLS | 0-RTT possible |
| Loss recovery | Per-connection | Per-stream |
| Congestion control | Conservative | Modern algorithms (BBR, CUBIC) |
| Head-of-line blocking | Yes | No |
QUIC was built by Google specifically for high-latency, lossy networks. It handles packet loss more gracefully and can push more data through the pipe.
Installation
Package Manager
# Debian/Ubuntu
sudo dpkg -i qcp_*.deb
# Arch Linux (AUR)
yay -S qcp
# macOS/Linux via Cargo
cargo install --locked qcp
# Nix
nix shell 'github:crazyscot/qcp?dir=nix'
From Release Binaries
Download from GitHub Releases:
.debpackages for Debian/Ubuntu- Static musl binaries for other Linux
- macOS and Windows archives
Important: Install qcp on both the local and remote machines. The remote binary must be in your PATH.
Basic Usage
The syntax mirrors scp:
# Copy local file to remote
qcp myfile.tar.gz server:/tmp/
# Copy remote file to local
qcp server:/var/log/app.log ./
# Copy directory recursively
qcp -r ./data/ server:/backup/
# Multiple sources
qcp file1.txt file2.txt server:/destination/
Example output:
$ qcp my-server:/tmp/testfile /tmp/
⠂ Transferring data 2.1MB/s (last 1s)
testfile ████████████████████████░░░░░░░░░░░░░ 1s @ 6.71 MB/s [10.49 MB]
How It Works
- qcp connects to the remote via SSH and launches
qcp --server - Both sides generate ephemeral TLS certificates and exchange them over SSH
- A QUIC session is established using these certificates
- Files transfer over QUIC with progress reporting
- SSH ensures authentication; QUIC handles the heavy lifting
This hybrid approach gives you SSH's security model with QUIC's performance.
Tuning for Your Network
The default configuration assumes 100Mbit symmetric bandwidth with 300ms RTT. For better performance, tune these values:
# Specify your actual bandwidth
qcp server:/file /tmp/ --rx 100M --tx 50M
# Also specify RTT if known
qcp server:/file /tmp/ --rx 100M --tx 50M --rtt 150
Persistent Configuration
Create ~/.qcp.conf:
Host *
Rx 100M
Tx 50M
Host us-west-server
Rx 500M
Tx 100M
Rtt 80
UDP Buffer Tuning
For best performance, increase UDP buffer sizes:
# Linux - add to /etc/sysctl.conf
net.core.rmem_max = 4194304
net.core.wmem_max = 4194304
# Apply
sudo sysctl -p
Firewall Considerations
qcp needs UDP connectivity to the remote host:
- If you're behind NAT (most home/office networks), it usually just works
- If the remote is firewalled, open a UDP port range and configure qcp:
qcp --remote-port 50000-50100 server:/file /tmp/
Or in config:
Host firewalled-server
RemotePort 50000-50100
Performance Comparison
Real-world results vary, but qcp typically shines on:
| Scenario | scp | qcp | Improvement |
|---|---|---|---|
| Same datacenter | 110 MB/s | 112 MB/s | ~same |
| Cross-continent (200ms RTT) | 15 MB/s | 45 MB/s | 3x |
| Lossy connection (1% loss) | 5 MB/s | 35 MB/s | 7x |
The bigger the latency or packet loss, the more qcp helps.
Comparison with Alternatives
| Tool | Protocol | Auth | Best For |
|---|---|---|---|
| scp | TCP/SSH | SSH keys | Local/low-latency |
| rsync | TCP/SSH | SSH keys | Incremental sync |
| qcp | QUIC/SSH | SSH keys | High-latency transfers |
| bbcp | TCP (parallel) | SSH | Bulk transfers (complex setup) |
| Aspera | FASP (UDP) | License | Enterprise (expensive) |
qcp fills the gap between scp (simple but slow) and enterprise solutions (fast but complex/costly).
Tips for SRE Teams
- Cross-region backups: Use qcp for copying database dumps between regions
- Log collection: Pull large log archives from remote DCs faster
- Deployment artifacts: Ship build artifacts to edge locations
- Disaster recovery: Speed up restore operations from remote backups
FAQ
Does qcp work with my existing SSH keys?
Yes. qcp uses your system's SSH binary and respects ~/.ssh/config, so existing keys and host aliases work.
Can I use qcp through a jump host?
Not directly yet, but you can use SSH's ProxyJump in your SSH config, and qcp will follow it for the initial connection.
Is qcp secure?
Yes. Authentication happens over SSH (same as scp). The QUIC session uses TLS 1.3 with ephemeral keys exchanged over the SSH channel.
Why not just use rsync?
rsync is great for incremental syncs, but it still uses TCP. For bulk transfers of new data over high-latency links, qcp will be faster.
Need to automate cross-region file transfers and monitor their performance? Akmatori helps SRE teams build AI-powered runbooks that can orchestrate complex operations across distributed infrastructure.
