Optimizing SSH Tunnel Performance for MySQL Queries: Solving High Latency Issues


2 views

When setting up an SSH tunnel for MySQL connections between VMs in my Vagrant environment, I encountered severe performance degradation - queries were running 5-80x slower through the tunnel versus direct connections. The basic tunnel setup looked like this:

ssh -N -L 3306:127.0.0.1:3306 sshuser@192.168.10.10

Interestingly, removing the -N (no command execution) flag restored performance to near-direct-connection levels, but created an unwanted interactive shell session.

The -N flag changes how SSH handles packet buffering and flow control. Without it:

  • SSH uses more aggressive TCP window sizing
  • Encryption/decryption happens in larger chunks
  • The connection maintains better throughput for database protocols

To maintain security while getting optimal performance:

# Option 1: Background with control socket
ssh -f -N -M -S /tmp/ssh_tunnel.sock -L 3306:localhost:3306 sshuser@192.168.10.10

# Later, to close:
ssh -S /tmp/ssh_tunnel.sock -O exit sshuser@192.168.10.10

# Option 2: Use autossh for resilience
autossh -M 0 -f -N -L 3306:127.0.0.1:3306 sshuser@192.168.10.10

SSH cryptographic overhead can be reduced with:

ssh -C -c aes128-gcm@openssh.com -o Compression=no \
  -L 3306:127.0.0.1:3306 sshuser@192.168.10.10

Key parameters:

  • -C: Enable compression (tradeoff between CPU and bandwidth)
  • -c aes128-gcm: Faster cipher than default
  • Compression=no: Sometimes helps with already-compressed database traffic

For production environments, consider setting up systemd services:


# /etc/systemd/system/mysql-tunnel.service
[Unit]
Description=MySQL SSH Tunnel
After=network.target

[Service]
User=sshuser
ExecStart=/usr/bin/ssh -NT -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=60 -o ServerAliveCountMax=3 \
  -L 3306:127.0.0.1:3306 sshuser@192.168.10.10
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

When using SSH tunnels for MySQL connections, many developers encounter significant performance degradation. The encryption process that makes SSH secure also introduces computational overhead. Through benchmarking, I've observed query slowdowns ranging from 5x to 80x compared to direct connections.

# Basic SSH tunnel command causing slowdown
ssh -N -L 3306:127.0.0.1:3306 sshuser@192.168.10.10

The -N flag tells SSH not to execute remote commands, which ironically creates our performance bottleneck. When removed, we see near-native speeds but get an interactive shell:

# Faster but creates shell session
ssh -L 3306:127.0.0.1:3306 sshuser@192.168.10.10

Rest assured, data remains fully encrypted regardless of the -N flag. The encryption occurs at the protocol level, not the session level.

For background operation without shell interference, consider these approaches:

# Option 1: Use ssh -f with -N for background operation
ssh -f -N -L 3306:127.0.0.1:3306 sshuser@192.168.10.10

# Option 2: Utilize autossh for resilient connections
autossh -M 0 -f -N -L 3306:127.0.0.1:3306 sshuser@192.168.10.10

# Option 3: Systemd service (create /etc/systemd/system/ssh-tunnel.service)
[Unit]
Description=MySQL SSH Tunnel
After=network.target

[Service]
User=sshuser
ExecStart=/usr/bin/ssh -N -L 3306:127.0.0.1:3306 sshuser@192.168.10.10
Restart=always

[Install]
WantedBy=multi-user.target

SSH offers multiple ciphers with varying performance characteristics. Benchmark different options:

# Test faster encryption algorithms
ssh -c aes128-gcm@openssh.com -L 3306:127.0.0.1:3306 sshuser@192.168.10.10
ssh -c aes128-ctr -L 3306:127.0.0.1:3306 sshuser@192.168.10.10

# Disable unused features for better performance
ssh -o Compression=no -o Ciphers=aes128-gcm@openssh.com -L 3306:127.0.0.1:3306 sshuser@192.168.10.10

Combine these techniques in your SSH config (~/.ssh/config):

Host mysql-tunnel
    HostName 192.168.10.10
    User sshuser
    LocalForward 3306 127.0.0.1:3306
    ServerAliveInterval 60
    ServerAliveCountMax 5
    Compression no
    Ciphers aes128-gcm@openssh.com
    ExitOnForwardFailure yes

Then establish the tunnel with simply:

ssh -fN mysql-tunnel

For high-performance requirements, consider:

  • MySQL native SSL support
  • VPN solutions like WireGuard
  • SSH Multiplexing with ControlMaster

Remember to benchmark each approach in your specific environment, as performance characteristics vary across different hardware and network conditions.