OpenVPN TCP Throughput Capped (~6 Mbps) Due to Hardcoded 64 KB Socket Buffer
OpenVPN's hardcoded 64 KB socket buffer (sndbuf/rcvbuf) prevents TCP Window Size Scaling from growing beyond 64 KB, capping throughput to approximately 5–7 Mbps on high-latency links regardless of available bandwidth or CPU headroom. The fix is to add 'sndbuf 0' and 'rcvbuf 0' to both server and client OpenVPN configuration files, restoring OS-managed buffer sizing. Removing the comp-lzo compression directive further eliminates single-core CPU bottlenecks that can persist after the buffer fix.
Indicators
- OpenVPN TCP throughput capped around 5–7 Mbps despite available high-bandwidth link
- Non-VPN transfers between the same hosts achieve near line-rate (e.g., ~88 Mbps on a 100 Mbps link)
- Low CPU utilization across all cores during OpenVPN transfers
- Ping latency over the OpenVPN tunnel increases significantly under iperf load compared to idle baseline
- iperf reports ~6 Mbits/sec over the VPN tunnel regardless of the number of parallel streams
Likely causes
- OpenVPN hardcoded 64 KB socket buffer (sndbuf/rcvbuf = 65536) prevents TCP Window Size Scaling from growing beyond 64 KB
- On high-latency links (e.g., 100 ms RTT), a 64 KB TCP window mathematically limits throughput to ~5 Mbps (64 KB ÷ 0.1 s = 5.12 Mbps)
- comp-lzo compression consuming excessive single-core CPU cycles, creating a secondary bottleneck after the buffer issue is resolved
- TCP-over-TCP encapsulation amplifying congestion and retransmission behaviour under load
Diagnostic steps
-
Run iperf between VPN tunnel IPs to measure baseline VPN throughput: on the server run 'iperf -s'; on the client run 'iperf -c <tunnel_server_ip>'.
-
Run the same iperf test directly between physical/LAN IPs (outside the VPN tunnel) to establish a non-VPN throughput baseline for comparison.
-
During the iperf test, run 'top' and press '1' to view per-core CPU utilization; check whether any single core is saturated while others remain idle.
-
During the iperf test, run 'ping <tunnel_peer_ip>' over the VPN and observe whether latency increases significantly compared to the idle tunnel baseline, indicating buffer saturation.
-
Inspect the OpenVPN server and client configuration files for sndbuf/rcvbuf directives; if absent or set to 65536, OpenVPN is using its hardcoded 64 KB default.
-
Calculate the theoretical maximum throughput: divide the socket buffer size in bytes by the RTT in seconds (e.g., 65536 ÷ 0.060 s ≈ 8.7 Mbps) and compare to the observed iperf result to confirm the buffer is the bottleneck.
-
Add 'sndbuf 0' and 'rcvbuf 0' to both the server and client OpenVPN configuration files, restart OpenVPN on both ends, and rerun iperf to verify throughput improvement.
-
If a single CPU core shows elevated utilization after the buffer fix, remove the 'comp-lzo' directive from both server and client configs, restart OpenVPN on both ends, and rerun iperf to confirm further improvement.
Resolution path
- Add 'sndbuf 0' to the OpenVPN server configuration file (/etc/openvpn/server.conf or equivalent).
- Add 'rcvbuf 0' to the OpenVPN server configuration file.
- Add 'sndbuf 0' to the OpenVPN client configuration file.
- Add 'rcvbuf 0' to the OpenVPN client configuration file.
- Restart the OpenVPN service on both server and client to apply the buffer changes.
- Retest throughput with iperf between tunnel IPs; confirm throughput rises significantly toward link capacity.
- If throughput improves but one CPU core is now saturated, remove the 'comp-lzo' directive from both server and client OpenVPN configuration files.
- Restart OpenVPN on both ends and retest with iperf to confirm the compression bottleneck is resolved.
Prevention
- Always include 'sndbuf 0' and 'rcvbuf 0' in OpenVPN configurations for any high-bandwidth or high-latency deployment.
- Avoid the comp-lzo compression directive for bulk data transfer workloads where single-core CPU saturation may become a bottleneck.
- Prefer UDP over TCP for OpenVPN tunnels to eliminate TCP-over-TCP retransmission amplification on congested or lossy links.
- Before deploying an OpenVPN tunnel, calculate the expected maximum throughput (buffer_size_bytes ÷ RTT_seconds) to identify buffer limitations early.
- Use 'push' directives in the server configuration to enforce sndbuf/rcvbuf settings on clients that cannot be individually managed.
- Include iperf throughput validation as part of VPN deployment acceptance testing to catch buffer and compression issues before production traffic is migrated.
Tools
- iperf — network throughput benchmarking between tunnel and physical IPs
- top — CPU utilization monitoring (press '1' for per-core view)
- ping — latency measurement over VPN tunnel under load
- OpenVPN — VPN daemon configuration (server.conf / client.conf)