Optimizing SSH for High-Latency and Unstable Network Connections


1 views

We've all been there - typing commands into an SSH session where each character appears with frustrating delay, or worse, getting disconnected mid-way through important work. This is especially common when:

  • Connecting to cloud servers across continents
  • Using mobile hotspots or shared WiFi
  • Working with satellite or rural internet connections

Add these to your ~/.ssh/config:

Host *
    ServerAliveInterval 30
    ServerAliveCountMax 5
    TCPKeepAlive yes
    Compression yes
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 1h

Mosh (Mobile Shell) is specifically designed for unstable connections:

# Installation
sudo apt-get install mosh  # Debian/Ubuntu
brew install mosh          # macOS

# Usage
mosh user@remote-server --predict=always

Key benefits:

  • Local echo shows typing immediately
  • Connection survives IP changes
  • Intelligent reconnection

Using tmux or screen ensures sessions survive disconnections:

# Start a persistent session
tmux new -s work_session

# Reattach after disconnect
tmux attach -t work_session

For extreme cases, consider these low-level tweaks:

# Reduce MTU for unstable links
sudo ifconfig eth0 mtu 1200

# Use alternative ports that might have better routing
ssh -p 443 user@remote-server

# Enable aggressive SSH compression
ssh -C -c aes128-gcm@openssh.com user@remote-server

This bash script maintains persistent connection:

#!/bin/bash
while true; do
    ssh -o "ExitOnForwardFailure yes" \
        -o "ServerAliveInterval 30" \
        user@remote-server
    sleep 5
    echo "Reconnecting..."
done

For immediate typing feedback:

  • Use rlwrap for local line editing: rlwrap ssh user@server
  • Configure your terminal emulator to show local keystrokes
  • Consider using a GUI SSH client with local echo option

When working with remote servers over high-latency connections (300ms+), traditional SSH behavior becomes painfully apparent. Each keystroke must:

  1. Travel to the remote server
  2. Be processed by the shell
  3. Return the updated display

This roundtrip creates the familiar "character-by-character" typing experience that drives developers mad.

Enable local echo in your SSH client to see typing instantly:

# For OpenSSH clients
ssh -o "StrictHostKeyChecking=no" -o "ServerAliveInterval=15" user@host

# In ~/.ssh/config (permanent solution)
Host *
    ServerAliveInterval 15
    TCPKeepAlive yes
    Compression yes
    EscapeChar ~

Mosh (Mobile Shell) was specifically designed for unstable connections:

# Installation
sudo apt install mosh  # Debian/Ubuntu
brew install mosh      # macOS

# Basic usage
mosh user@host --predict=always

# Advanced configuration
export MOSH_PREDICTION_DISPLAY=always
mosh --ssh="ssh -p 2222" user@host

Key advantages:

  • Local echo by default
  • Connection roaming (IP changes don't break session)
  • Predictive typing for high latency
  • UDP-based protocol handles packet loss better

When connections drop, these tools preserve your session:

# tmux example
tmux new -s remote_work
# Detach with Ctrl+b d
# Reattach after reconnect:
tmux attach -t remote_work

# screen alternative
screen -S project_session
# Detach with Ctrl+a d

Tweak your SSH configuration for better performance:

# In /etc/ssh/sshd_config (server-side)
ClientAliveInterval 60
TCPKeepAlive yes
Compression delayed

# Client-side ~/.ssh/config optimizations
Host slow-connection
    HostName example.com
    User developer
    Compression yes
    Ciphers aes128-gcm@openssh.com
    MACs umac-64-etm@openssh.com
    ServerAliveInterval 30
    ServerAliveCountMax 5

When all else fails:

  • Use SSH connection hopping through intermediate servers closer to you
  • Write scripts locally and transfer/execute them remotely
  • Consider a VPN to stabilize the connection path
  • For critical work, setup a persistent reverse SSH tunnel
# Reverse tunnel example (run on remote server)
autossh -M 0 -N -R 2222:localhost:22 user@your-local-machine