Skip to content

Server Tuning

This page covers operating-system-level tuning for the R-VPN server, especially for high-latency or lossy international paths (for example, clients in China connecting to a server in the US).

Symptoms that tuning can help

  • Ping through the VPN starts reasonable but grows over time (e.g. 500 ms → 5–12 seconds).
  • Throughput collapses to tens of kbps even though the server has plenty of bandwidth.
  • ss -ti shows a very small congestion window (cwnd: 2), high retransmits, and bytes_retrans climbing.
  • The same client and server work fine on a different network (e.g. mobile 5G vs. fixed-line Wi-Fi).

These symptoms usually mean the TCP connection between the client and server is crossing a lossy or heavily shaped link. The default Linux congestion controller, CUBIC, interprets packet loss as network congestion and aggressively shrinks the send window, causing latency to spiral.

Switch to BBR congestion control

BBR (Bottleneck Bandwidth and RTT) models the link instead of treating loss as congestion. On high-loss, high-RTT paths it keeps throughput much higher and latency much more stable than CUBIC.

Check available algorithms

sysctl net.ipv4.tcp_available_congestion_control

If bbr is not listed, load the module:

sudo modprobe tcp_bbr

To load tcp_bbr automatically at boot, create /etc/modules-load.d/tcp_bbr.conf:

tcp_bbr

Apply BBR now

sudo sysctl -w net.ipv4.tcp_congestion_control=bbr

Persist BBR across reboots

Create /etc/sysctl.d/99-rvpn-tcp-tuning.conf:

# R-VPN TCP tuning for high-latency / lossy international paths
net.ipv4.tcp_congestion_control=bbr
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 262144 16777216
net.ipv4.tcp_wmem=4096 262144 16777216
net.ipv4.tcp_notsent_lowat=16384

Apply it:

sudo sysctl --system

The buffer increase gives each TCP connection enough headroom for the bandwidth-delay product of a 250–350 ms RTT path.

Verify the active connection is using BBR

After reconnecting the VPN client (existing connections keep their old congestion controller):

sudo ss -ti | grep -A5 'YOUR_CLIENT_IP'

Look for:

bbr wscale:...

If it still says cubic, the client has not reconnected yet.

FreeBSD tuning

FreeBSD also supports BBR through the cc_bbr kernel module, which is the best choice for high-loss, high-RTT paths.

Load BBR

Check whether the module is already loaded:

kldstat | grep cc_bbr

If it is not loaded:

sudo kldload cc_bbr

To load it automatically at boot, add this line to /boot/loader.conf:

cc_bbr_load="YES"

Apply BBR and tune buffers

sudo sysctl net.inet.tcp.cc.algorithm=bbr
sudo sysctl kern.ipc.maxsockbuf=16777216
sudo sysctl net.inet.tcp.recvspace=16777216
sudo sysctl net.inet.tcp.sendspace=16777216

To persist these settings across reboots, create /etc/sysctl.conf:

# R-VPN TCP tuning for high-latency / lossy international paths
net.inet.tcp.cc.algorithm=bbr
kern.ipc.maxsockbuf=16777216
net.inet.tcp.recvspace=16777216
net.inet.tcp.sendspace=16777216

Verify on FreeBSD

Check the active congestion controller:

sysctl net.inet.tcp.cc.algorithm

FreeBSD does not expose per-connection congestion-control names as conveniently as Linux ss, so verify throughput and latency with ping and iperf3 after reconnecting the client.

Other things to check

  • Interface MTU: Google Cloud VPC uses a 1460-byte MTU by default. R-VPN’s TUN MTU is 1420, which fits comfortably inside the VPC MTU plus TLS/WebSocket overhead.
  • CPU: rvpn-server is single-threaded for crypto per connection but async; a 1-vCPU VM is usually enough for one or two clients but may become a bottleneck at higher throughput.
  • Disk / logging: at default INFO verbosity the server logs every frame. On a busy client this can generate a lot of journald I/O. Consider reducing log verbosity in production.

When tuning does not help

If latency and loss persist after BBR and buffer tuning, the problem is likely outside the server:

  • ISP/routing issues on the international segment
  • Carrier-grade DPI or throttling targeting TLS on port 443
  • Local Wi-Fi router with aggressive QoS or small buffers

In those cases, try a different client network (mobile hotspot, different ISP) or a different server location closer to the client.