In this guide, you will learn Linux Kernel network tuning to improve throughput, reduce latency, and increase connection scalability on production servers. You can use this setup for real-world workloads, including API backends, reverse proxies, storage replication, and an AI/GPU pipeline, where default Linux networking values often become a bottleneck under sustained traffic.
At Perlod Hosting, these optimizations are most useful for high-performance VPS and dedicated servers, which help you get faster downloads and uploads, keep connections stable under heavy traffic, and improve performance for latency-sensitive services.
This guide applies to both flexible VPS servers and dedicated servers, especially when you need stable performance under high traffic.
Prerequisites for Linux Kernel Network Tuning
Before applying any Linux kernel tuning, make sure the server meets a few basic requirements and that you can safely roll back if needed.
Required access includes:
- Root or sudo privileges on the Linux server.
- Kernel version 4.9+ for TCP BBR support.
- Backup plan before making changes.
You can back up your sysctl configuration with the command below, so you can restore it if something goes wrong:
sudo cp /etc/sysctl.conf /etc/sysctl.conf.bak
Check your current kernel version:
If the version is 4.9+, you’re good to continue; if it’s older, you should upgrade the kernel first.
Step 1: Analyze Current Linux System Limitations
Before Linux kernel tuning, we must understand what's limiting the network performance.
You can check current TCP buffer settings with the following commands:
echo "=== TCP Read Memory ===" && sysctl net.ipv4.tcp_rmemecho "=== TCP Write Memory ===" && sysctl net.ipv4.tcp_wmemecho "=== Congestion Control ===" && sysctl net.ipv4.tcp_congestion_controlecho "=== QDisc (Queuing Discipline) ===" && sysctl net.core.default_qdisc
In your output, you must see something similar to these:
net.ipv4.tcp_rmem = 4096 131072 6291456net.ipv4.tcp_wmem = 4096 16384 4194304net.ipv4.tcp_congestion_control = cubicnet.core.default_qdisc = pfifo_fast
Explanations:
- tcp_rmem: The system will allocate 4KB–6MB per connection for reading.
- tcp_wmem: The system will allocate 4KB–4MB per connection for writing.
- cubic: Default congestion control designed for LAN.
- pfifo_fast: Basic FIFO queue.
Then, you can check the core system limits with the commands below:
echo "=== Core Buffer Maximums ===" && sysctl net.core.rmem_max net.core.wmem_maxecho "=== Network Device Backlog ===" && sysctl net.core.netdev_max_backlogecho "=== TCP Auto-tuning ===" && sysctl net.ipv4.tcp_moderate_rcvbufecho "=== File Descriptors ===" && sysctl fs.file-max
net.core.rmem_max = 212992 (208 KB - too small!)net.core.wmem_max = 212992 (208 KB - too small!)net.core.netdev_max_backlog = 1000 (will drop packets at scale)net.ipv4.tcp_moderate_rcvbuf = 1 (good, auto-tuning is on)fs.file-max = 794974 (OK, but can be increased)
Also, check the network interface speed with the following command:
ethtool eth0 | grep "Speed:"
Speed: 10000Mb/s ← 10 Gbps connection
Or for multiple interfaces, you can use:
for iface in eth0 eth1 eth2; do echo "$iface: $(ethtool $iface 2>/dev/null | grep Speed)"; done
Step 2: Calculate Required Buffer Size
At this point, you can calculate the required buffer size using the Bandwidth-Delay Product (BDP). BDP estimates how much data must be in flight on the network path to fully utilize the available bandwidth, so it gives a practical minimum for your TCP buffer sizing.
Use the formula below to compute BDP in bytes:
BDP (bytes) = Bandwidth (bits/sec) × RTT (seconds) / 8
Now you can plug in your bandwidth and measured RTT to get a target buffer size for high-throughput transfers.
Example 1: Long-Distance 100 Gbps Connection
- Bandwidth: 100 Gbps
- Typical RTT: ~60 ms (0.06 seconds)
Calculation:
BDP = (100,000,000,000 bits/sec) × (0.06 sec) / 8BDP = 6,000,000,000 bits / 8BDP = 750,000,000 bytesBDP = 750 MB
Recommended TCP buffer: 750 MB minimum. We will use 512 MB for safety.
Example 2: Moderate 10 Gbps Connection
- Bandwidth: 10 Gbps
- Typical RTT: ~80 ms (0.08 seconds)
Calculation:
BDP = (10,000,000,000) × (0.08) / 8BDP = 100,000,000 bytesBDP = 100 MB
Recommended TCP buffer: 100 MB minimum.
To measure your actual RTT, ping your target destination. For example, 8.8.8.8 for Google's DNS:
ping -c 20 8.8.8.8 | tail -1
round-trip min/avg/max/stddev = 8.5/11.2/15.3/2.1 ms
Or measure RTT to a specific server:
ping -c 10 1.1.1.1 | grep avg for i in {1..20}; do ping -c 1 -W 1 8.8.8.8 2>/dev/null | grep time=; done | awk -F'=' '{print $NF}' | sort -n | tail -5
Step 3: Edit the Sysctl Configuration File
In this step, you can make your Linux kernel tuning persistent by adding the kernel networking settings to /etc/sysctl.conf, so they survive reboots and apply consistently across the server. These parameters control core TCP behavior, which directly impacts throughput and latency on high-speed WAN links like 10G and 100G.
Open the sysctl configuration file with the command below:
sudo sysctl -p /etc/sysctl.conf
At the end of the file, add the following settings:
net.ipv4.tcp_rmem = 4096 131072 536870912net.ipv4.tcp_wmem = 4096 131072 536870912 net.core.rmem_max = 536870912net.core.wmem_max = 536870912net.core.rmem_default = 131072net.core.wmem_default = 131072 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_congestion_control = bbr net.core.default_qdisc = fq net.ipv4.tcp_max_syn_backlog = 8192net.core.somaxconn = 8192net.core.netdev_max_backlog = 8192 net.ipv4.tcp_sack = 1 net.ipv4.tcp_fack = 1 net.ipv4.tcp_timestamps = 1 net.ipv4.tcp_fastopen = 3 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 net.ipv4.ip_local_port_range = 10000 65535 net.ipv4.tcp_mtu_probing = 1 net.ipv4.tcp_slow_start_after_idle = 0 net.ipv4.tcp_moderate_rcvbuf = 1 net.ipv4.tcp_notsent_lowat = 16384 net.ipv4.tcp_keepalive_time = 300net.ipv4.tcp_keepalive_probes = 3net.ipv4.tcp_keepalive_intvl = 15 fs.file-max = 2097152 net.nf_conntrack_max = 1000000net.netfilter.nf_conntrack_max = 1000000
Once you are done, save and close the file.
Apply the Linux kernel tuning changes by reloading the configuration:
sudo sysctl -p /etc/sysctl.conf
Then, use this command to check for errors:
If you see errors like this:
sysctl: cannot stat /proc/sys/net/netfilter/nf_conntrack_max: No such file or directory
This is OK, your kernel doesn't support that particular parameter, and other parameters will still be applied.
Step 4: Enable TCP BBR Congestion Control for Linux Kernel Tuning
TCP BBR is Google's modern congestion control algorithm designed to keep throughput high while avoiding the latency spikes you often see on high-bandwidth, high-RTT paths.
You can load the BBR module with the command below:
The number after tcp_bbr is the reference count. Either 0 or another number is fine.
To make BBR load automatically on boot, create a module load configuration:
echo "tcp_bbr" | sudo tee -a /etc/modules-load.d/bbr.conf
cat /etc/modules-load.d/bbr.conf
In the output, you must see:
Also, you can enable the FQ (Fair Queuing) queue discipline, which is commonly paired with BBR to reduce bufferbloat under load:
echo "sch_fq" | sudo tee -a /etc/modules-load.d/fq.conf
Step 5: Confirm BBR, FQ, and Buffers Are Active
At this point, you can validate that your Linux kernel tuning and TCP tuning actually took effect, not just that it was added to a config file.
Check Congestion Control with:
sysctl net.ipv4.tcp_congestion_control
Example Output:net.ipv4.tcp_congestion_control = bbr
sysctl net.core.default_qdisc
Example output:net.core.default_qdisc = fq
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem
Example output:net.ipv4.tcp_rmem = 4096 131072 536870912net.ipv4.tcp_wmem = 4096 131072 536870912
sysctl net.ipv4.tcp_window_scaling
Example output:net.ipv4.tcp_window_scaling = 1
See All Active Connections and Their Congestion Control:
State Recv-Q Send-Q Local Address:Port Peer Address:PortESTAB 0 0 192.168.1.100:5201 192.168.1.200:60234ESTAB 0 0 192.168.1.100:5202 192.168.1.201:60235
For a more detailed TCP state, you can use:
For connections using BBR specifically, you can use:
Step 6: Benchmark Throughput with iperf3
This step turns your tuning into measurable results by running controlled throughput tests with iperf3 between two endpoints.
Install iperf3 based on your distro with the commands below:
sudo apt update && sudo apt install iperf3 -y sudo dnf install iperf3 -y
Then, start the iperf3 Server with the command below. Run on the server that will receive data:
Now run on a different machine (iPerf3 Client), or use localhost for testing:
iperf3 -c 192.168.1.100 -p 5201 -t 30 -P 4
Next, you can measure the download or reverse speed:
iperf3 -c 192.168.1.100 -p 5201 -t 30 -P 4 -R
The -R flag reverses the test direction, server sends, and client receives.
You can stop the server with the command below:
Step 7: Monitor Network Performance in Real-Time
In this step, you can monitor your network performance in real-time, so you can confirm your tuning is delivering stable throughput without hidden issues like rising latency, queue buildup, or retransmissions.
To monitor bandwidth usage, you can use the bmon tool:
sudo apt install bmon -ybmon -o ascii
Press h for help, q to quit.
For monitoring connections and bandwidth per process, you can use the nethogs tool:
sudo apt install nethogs -ysudo nethogs eth0
To monitor TCP Socket Statistics, you can run:
To check current latency, you can run:
ping -c 20 192.168.1.100 | tail -1
Monitor TCP retransmissions with the command below:
watch -n 1 'cat /proc/net/snmp | grep Tcp'
Lower TcpRetransSegs is better.
You can compare the benchmark results and see the improvements.
Advanced Linux Kernel Tuning for Extreme High-Performance
These optional tuning parameters focus on eliminating host-side bottlenecks that occur at 100 Gbps and above, particularly CPU power management, NUMA effects, and NIC queue limits.
For 100+ Gbps Networks:
Set CPU Governor to Performance Mode:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor sudo apt install cpupower -ysudo cpupower frequency-set -g performance cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
Disable CPU Power Saving:
sudo nano /etc/default/grub sudo update-grubsudo reboot
Enable NUMA Affinity for Multi-Socket Servers:
numactl --hardware numactl --cpunodebind=0 --preferred=0 ./your-application
Increase RX/TX Ring Buffer:
ethtool -g eth0 sudo ethtool -G eth0 rx 4096 tx 4096
Disable Swap for Ultra-Low Latency:
free -h sudo swapoff -a sudo nano /etc/fstab
Conclusion
Linux Kernel network tuning is most effective when it’s done methodically by measuring a baseline, applying a small set of proven kernel changes, verifying they actually took effect, and then re-testing under real load.
The best improvements usually come from three things: using the right congestion control (often BBR), pairing it with a matching queue setup (like FQ), and setting TCP buffer sizes based on your actual bandwidth and latency (BDP).
If you’re running high-traffic services, these kernel-level optimizations can remove hidden bottlenecks and make performance more stable.
We hope you enjoy this Linux kernel tuning guide. Subscribe to our X and Facebook channels to get the latest updates and articles.
For further reading:
Setting up remote management with IPMI
Building a High-Availability Cluster with Corosync and Pacemaker