VPS Network and TCP Kernel Tuning: Maximize Throughput, Reduce Latency, and Handle More Connections

VPS Network and TCP Kernel Tuning: Maximize Throughput, Reduce Latency, and Handle More Connections

The Linux kernel’s default network settings are conservative — optimized for general compatibility rather than VPS workloads handling thousands of concurrent connections. A few sysctl parameter changes can significantly reduce latency, increase throughput, and allow your VPS to handle 10–100× more simultaneous connections without additional hardware. This guide covers the highest-impact TCP kernel settings for web server workloads.

Before Tuning: Understand the Baseline

<code"># Current connection count
ss -s
# Or: netstat -s | grep -E "connections|packets"

# Maximum file descriptors (related to max connections)
ulimit -n   # Per-process limit
cat /proc/sys/fs/file-max   # System-wide limit

# Current TCP settings
sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog
sysctl net.core.rmem_max
sysctl net.core.wmem_max

Step 1: Apply Kernel Tuning Settings

<code">sudo nano /etc/sysctl.d/99-vps-performance.conf
<code"># ─────────────────────────────────────────────────────────
# FILE DESCRIPTORS — maximum open files (connections)
# ─────────────────────────────────────────────────────────
fs.file-max = 2097152
fs.nr_open = 2097152

# ─────────────────────────────────────────────────────────
# NETWORK — connection queues
# ─────────────────────────────────────────────────────────

# Maximum connections waiting in Nginx/application accept queue
# Default is 128 — too low for busy servers
net.core.somaxconn = 65535

# Maximum SYN backlog (half-open connections waiting to complete handshake)
net.ipv4.tcp_max_syn_backlog = 65535

# ─────────────────────────────────────────────────────────
# TCP BUFFERS — throughput for high-bandwidth connections
# ─────────────────────────────────────────────────────────

# Socket receive buffer size (min, default, max) in bytes
net.core.rmem_default = 262144
net.core.rmem_max = 67108864   # 64 MB max receive buffer

# Socket send buffer size
net.core.wmem_default = 262144
net.core.wmem_max = 67108864   # 64 MB max send buffer

# TCP receive/send buffer auto-tuning range (min, pressure, max)
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864

# ─────────────────────────────────────────────────────────
# BBR CONGESTION CONTROL — better throughput over the internet
# ─────────────────────────────────────────────────────────

# Enable BBR (Google's TCP congestion control algorithm — better than CUBIC)
# BBR significantly improves throughput for connections with packet loss
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# ─────────────────────────────────────────────────────────
# TIME_WAIT — reclaim ports faster
# ─────────────────────────────────────────────────────────

# Maximum number of TIME_WAIT sockets
net.ipv4.tcp_max_tw_buckets = 2000000

# Reuse TIME_WAIT sockets for outbound connections
net.ipv4.tcp_tw_reuse = 1

# Fast recycling of TIME_WAIT sockets (for outbound connections)
# net.ipv4.tcp_tw_recycle = 1   # REMOVED in kernel 4.12+ — don't use

# TIME_WAIT timeout (seconds) — default is 60
# Lower to free ports faster (safe for web server workloads)
net.ipv4.tcp_fin_timeout = 30

# ─────────────────────────────────────────────────────────
# CONNECTION HANDLING
# ─────────────────────────────────────────────────────────

# Number of times to retry SYN before giving up
net.ipv4.tcp_syn_retries = 2

# Reduce SYN-ACK retry count (faster failure detection)
net.ipv4.tcp_synack_retries = 2

# Keepalive: detect dead connections faster
net.ipv4.tcp_keepalive_time = 600       # Start keepalive probes after 600s idle
net.ipv4.tcp_keepalive_intvl = 30       # Probe interval
net.ipv4.tcp_keepalive_probes = 5       # Probes before declaring dead

# ─────────────────────────────────────────────────────────
# SECURITY
# ─────────────────────────────────────────────────────────

# SYN cookies: protection against SYN flood attacks
net.ipv4.tcp_syncookies = 1

# Ignore ICMP redirects (prevent routing manipulation)
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# Ignore source routing (prevent IP spoofing)
net.ipv4.conf.all.accept_source_route = 0

# Log martian packets (packets with impossible source addresses)
net.ipv4.conf.all.log_martians = 1

# ─────────────────────────────────────────────────────────
# MEMORY
# ─────────────────────────────────────────────────────────

# Shared memory (for PostgreSQL, etc.)
kernel.shmmax = 68719476736   # 64 GB
kernel.shmall = 4294967296
<code"># Apply settings immediately
sudo sysctl -p /etc/sysctl.d/99-vps-performance.conf

# Verify BBR is active
sysctl net.ipv4.tcp_congestion_control
# Should output: net.ipv4.tcp_congestion_control = bbr

Step 2: Increase File Descriptor Limits

<code">sudo nano /etc/security/limits.conf
<code"># Add at the end:
*         soft    nofile    1048576
*         hard    nofile    1048576
root      soft    nofile    1048576
root      hard    nofile    1048576
<code">sudo nano /etc/systemd/system.conf
<code">[Manager]
DefaultLimitNOFILE=1048576
<code">sudo systemctl daemon-reexec
# Log out and back in, then verify:
ulimit -n   # Should show 1048576

Step 3: Configure Nginx to Use Increased Limits

<code">sudo nano /etc/nginx/nginx.conf
<code">worker_processes auto;
worker_rlimit_nofile 1048576;   # Match the system limit

events {
    worker_connections 65535;   # Was 1024 — now much higher
    use epoll;                  # Linux event model (fastest on Linux)
    multi_accept on;            # Accept multiple connections at once
}

http {
    # TCP optimizations
    tcp_nopush on;    # Send headers + first data chunk together
    tcp_nodelay on;   # Disable Nagle algorithm — lower latency
    sendfile on;      # Use sendfile() for static files (zero-copy)
}
<code">sudo nginx -t && sudo systemctl reload nginx

Step 4: Verify BBR is Working

<code"># Confirm BBR is the active congestion control algorithm
sysctl net.ipv4.tcp_congestion_control
# Output: net.ipv4.tcp_congestion_control = bbr

# Check available congestion control algorithms
sysctl net.ipv4.tcp_available_congestion_control

# If BBR is not available (older kernel):
sudo modprobe tcp_bbr
echo "tcp_bbr" | sudo tee -a /etc/modules-load.d/bbr.conf
sudo sysctl net.ipv4.tcp_congestion_control=bbr

Step 5: Benchmark Before and After

<code"># Test TCP connection handling
ab -n 10000 -c 500 https://yourdomain.com/

# Test with a tool that handles connection reuse better
wrk -t4 -c400 -d30s https://yourdomain.com/

# Network throughput test (from another server)
iperf3 -s   # Server mode on VPS
iperf3 -c YOUR_VPS_IP   # Client mode from another server

Settings to Avoid

  • net.ipv4.tcp_tw_recycle: Removed in kernel 4.12 — using it causes problems with NAT and load balancers
  • net.ipv4.ip_local_port_range extremes: Default 32768 60999 is usually fine; only expand if seeing “Cannot assign requested address” errors
  • Very large somaxconn (>65535): Generally diminishing returns; fix your application’s connection handling instead

Getting Started

These kernel settings are safe to apply on any Ubuntu VPS at VPS.DO running kernel 4.9+ (all current Ubuntu LTS versions). The BBR congestion control algorithm provides the largest real-world improvement for internet-facing services — improved throughput for users on high-latency or lossy connections (mobile, intercontinental). Settings survive reboots when placed in /etc/sysctl.d/.

Conclusion

Linux TCP kernel tuning delivers three main benefits: higher connection capacity (via increased somaxconn and file descriptor limits), better throughput (via BBR congestion control and larger socket buffers), and faster port recycling (via tcp_tw_reuse and reduced tcp_fin_timeout). These changes require no additional software, take effect immediately with sysctl -p, and persist across reboots. For high-traffic VPS deployments, kernel tuning is often the difference between a server that struggles at 1,000 concurrent connections and one that handles 10,000+.

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!