The default Linux kernel parameters are tuned conservatively for general workloads. A WordPress server handling thousands of concurrent visitors benefits from a small set of sysctl tweaks: larger TCP buffers, faster TIME_WAIT recycling, increased file-descriptor limits, and a more aggressive vm.swappiness. These changes require no reboot and can be applied live.
Problem: A WordPress server under traffic spikes shows high kernel CPU usage, TCP backlog drops, and connection timeouts — the Linux network stack is tuned for desktop defaults, not for a high-concurrency web server.
Solution: Tune net.core.somaxconn, net.ipv4.tcp_max_syn_backlog, and net.ipv4.tcp_fin_timeout via sysctl to handle more concurrent connections. Enable TCP BBR congestion control with net.ipv4.tcp_congestion_control = bbr for better throughput. Set fs.file-max and PHP-FPM rlimit_files to avoid file descriptor exhaustion.
The configuration below covers the most impactful TCP and memory settings for a LEMP (Linux, Nginx, MySQL, PHP-FPM) WordPress stack, explains each parameter, and shows how to make the changes permanent via /etc/sysctl.d/.
# /etc/sysctl.d/99-wordpress.conf
# Apply with: sysctl --system (or: sysctl -p /etc/sysctl.d/99-wordpress.conf)
# ── TCP send/receive buffer sizes (bytes) ────────────────────────────────
net.core.rmem_max = 134217728 # 128 MiB max read buffer
net.core.wmem_max = 134217728 # 128 MiB max write buffer
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
# ── Increase listen backlog and connection queue ──────────────────────────
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# ── Recycle TIME_WAIT sockets faster (safe behind a load balancer) ────────
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# ── BBR congestion control (requires kernel 4.9+) ─────────────────────────
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# ── File descriptor limits ────────────────────────────────────────────────
fs.file-max = 2097152
# ── Virtual memory: avoid swapping unless absolutely necessary ────────────
vm.swappiness = 10 # default 60 — reduce swap use
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
# Verify BBR is active after reboot
sysctl net.ipv4.tcp_congestion_control
# Expected: net.ipv4.tcp_congestion_control = bbr
# Check current open file descriptors vs limit
cat /proc/sys/fs/file-nr
# columns: open_fds 0 max_fds
# Raise per-process fd limit for Nginx and PHP-FPM in their systemd unit
# /etc/systemd/system/nginx.service.d/override.conf
# [Service]
# LimitNOFILE=65535
systemctl daemon-reload && systemctl restart nginx php8.2-fpm
NOTE: net.ipv4.tcp_tw_reuse = 1 is only safe when your server sits behind a NAT or load balancer; on a server with a direct public IP, enabling it alongside tcp_timestamps = 1 (the default) is sufficient — never enable the deprecated tcp_tw_recycle option as it breaks connections from NAT'd clients.