Set Linux sysctl for a Site That Gets Lots of Hits
Linux ships with small limits, and they slow your site when hits jump. Here is how to set socket queues, BBR, and file limits for 10,000 live links on a full box.
Default Linux settings suit a home PC. They do not suit a busy web host. Web hits jump. The queues fill fast. This happens fast on phone networks in India. A burst of guests can clog the buffers. Then Linux drops SYN packets. Web guests wait longer. Their pages load slowly. Real-time AI search bots drop slow pages. They cite quick sites instead.
You can fix this on a managed app server. You need
no new hardware. You need tuned socket queues. You need TCP BBR speed
control. You need the right file caps. This guide shows how to tune
/etc/sysctl.conf for 10,000 or more live links.
How the TCP handshake works.
When a guest loads your site, the browser starts a TCP three-way handshake. Linux runs it through two queues.
- The SYN queue holds half open links. The client sends a SYN. Linux sends back SYN-ACK. It holds the link here. It waits for the last ACK from the client.
- The accept queue holds live links. The handshake ends. It goes to
the next queue. It waits until your web host calls
accept().
Incoming Client SYN
│
▼
┌───────────────────────────────┐
│ SYN Backlog Queue │ <── Controlled by net.ipv4.tcp_max_syn_backlog
│ (Half-Open Handshakes) │
└───────────────┬───────────────┘
│ Client returns ACK
▼
┌───────────────────────────────┐
│ Accept Backlog Queue │ <── Controlled by net.core.somaxconn
│ (Established Sockets) │
└───────────────┬───────────────┘
│ Web server calls accept()
▼
┌───────────────────────────────┐
│ Nginx / Web Worker Pool │ <── Reads HTTP request headers
└───────────────────────────────┘
If the accept queue fills, Linux drops new links. If the SYN queue fills, no new guest can link. Tune both queues. That stops lost links under load.
Socket queue tuning: fixing queue drops.
In short: Set net.core.somaxconn and net.ipv4.tcp_max_syn_backlog to 65535. Then set your web host queue to match.
The base value of net.core.somaxconn is 128 or 4096. A quick burst of hits
can fill a queue of 128 links. That takes a few milliseconds. Once full,
the host drops new packets.
Tune the accept queue (somaxconn).
The net.core.somaxconn rule sets the top queue depth for listen()
sockets. Raise this cap. It lets you take lots of live visits.
sysctl -w net.core.somaxconn=65535
Your web host must ask for this queue size. In Nginx, change the
listen rule in your host block.
server {
listen 443 ssl default_server backlog=65535;
listen [::]:443 ssl default_server backlog=65535;
server_name example.com;
}
If you do not set backlog in Nginx, it uses 511. Linux picks the
smaller one.
Tune the SYN queue (tcp_max_syn_backlog).
The net.ipv4.tcp_max_syn_backlog rule sets how many half open links
Linux keeps in RAM. When hits surge, clients take time to send the last
packet.
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
Tune the network card queue (netdev_max_backlog).
Cards can take frames faster than Linux threads can read them. The
frames wait in net.core.netdev_max_backlog. The base is 1000. It
drops frames in a quick spike. Raise it to 16384.
sysctl -w net.core.netdev_max_backlog=16384
| Setting | Base | New | What it does. |
|---|---|---|---|
net.core.somaxconn | 128 to 4096 | 65535 | Max sockets in the accept queue. |
net.ipv4.tcp_max_syn_backlog | 512 to 1024 | 65535 | Max half open SYN links. |
net.core.netdev_max_backlog | 1000 | 16384 | Packet queue for the network card. |
TCP link reuse and port use.
In short: Turn on net.ipv4.tcp_tw_reuse, drop net.ipv4.tcp_fin_timeout to 15 seconds, and widen the port range.
When your web host closes a link, the socket stays in TIME_WAIT
state. It waits up to 60 seconds. This wait lets old packets clear
the path.
On busy reverse proxies, thousands pile up. They all sit in TIME_WAIT
state. This state uses up free ports. It uses up RAM.
Reuse links with tcp_tw_reuse.
The net.ipv4.tcp_tw_reuse rule lets Linux reuse them for new links. It
is safe for web hosts. It is safe for proxies.
sysctl -w net.ipv4.tcp_tw_reuse=1
[!WARNING] Never turn on
net.ipv4.tcp_tw_recycle. Modern Linux cut it. It drops links from clients behind phone routers. It does the same for clients behind shared NAT links.
Cutting tcp_fin_timeout.
The net.ipv4.tcp_fin_timeout rule sets how long Linux holds a socket.
It sits in FIN-WAIT-2 state. The base is 60 seconds. On web hosts,
drop it to 15 seconds.
sysctl -w net.ipv4.tcp_fin_timeout=15
Open the port range.
When Nginx proxies calls to back-end tools, it opens a port. Tools like PHP-FPM, Node.js, or Redis are common. The base range is 32768 to 60999 (about 28,231 ports). Under load, you can run out of ports.
Open it. That allows up to 64,511 ports.
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
TCP BBR vs Cubic.
In short: Turn on TCP BBR to keep speeds high and stop speed drops on phone networks.
Cubic is the norm on most Linux. Cubic thinks packet loss means the load is too high. When a packet drops, Cubic cuts link speed in half.
On phone 4G and 5G networks in India, packet loss comes from radio noise. It comes from tower hops too. It is not caused by a heavy load. Cubic slows down by mistake. This makes page loads slow. It raises Time to First Byte.
Google built BBR to fix this issue. BBR stands for Bottleneck Bandwidth and Round-trip Time. BBR checks the real pipe width and delay fast. It skips small packet loss. It keeps link speed high.
# Set default queueing discipline to Fair Queueing
sysctl -w net.core.default_qdisc=fq
# Enable BBR congestion control
sysctl -w net.ipv4.tcp_congestion_control=bbr
| Metric | Cubic Mode | BBR Mode | Phone User Impact. |
|---|---|---|---|
| Congestion check | Packet loss events. | Bandwidth and round trip time. | BBR ignores radio signal loss. |
| Speed after 2% loss | Drops by up to 50%. | Stays at full link rate. | Up to 3x faster link rate. |
| Median response wait | Shifts. | Low and steady. | Faster TTFB and lower bounce rates. |
| Buffer bloat defense | Poor. | Strong. | Smoother Core Web Vitals. |
To learn how low delay boosts web speed, see our guide on server-side TTFB speed.
TCP RAM buffer caps for a VPS.
In short: Set buffer caps to boost speed without draining RAM.
Each live link claims read and write buffers in RAM. Linux tunes these on the fly. You must set safe caps.
The rules use three numbers: floor, base, and top bytes.
# TCP receive buffer: min 4KB, default 87KB, max 16MB
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
# TCP send buffer: min 4KB, default 65KB, max 16MB
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
# Maximum OS socket receive and send limits
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
RAM buffer caps across VPS tiers.
Do not set top buffers too high on small RAM nodes. If 10,000 sockets all grow to 16 MB at once, your host runs out of RAM.
Use these safe caps for your cloud host size.
| VPS Tier | RAM Size | Top rmem_max | Top wmem_max | Safe Socket Count. |
|---|---|---|---|---|
| Starter | 1 GB | 4,194,304 (4 MB) | 4,194,304 (4 MB) | Up to 2,500 links. |
| Growth | 2 GB | 8,388,608 (8 MB) | 8,388,608 (8 MB) | Up to 5,000 links. |
| Pro | 4 GB | 16,777,216 (16 MB) | 16,777,216 (16 MB) | Up to 15,000 links. |
| Business | 8 GB | 33,554,432 (32 MB) | 33,554,432 (32 MB) | Up to 30,000 links. |
| Enterprise | 16 GB+ | 67,108,864 (64 MB) | 67,108,864 (64 MB) | 50,000+ links. |
To tune back-end workers, read our guide on PHP-FPM worker pool tuning. Learn how fast local storage cuts disk wait limits.
File caps and process limits.
In short: In Linux, sockets are files. Set system and user file caps to at least 65535.
Each live link takes a file descriptor. So does each log file. So does each static asset. The base user cap is often 1024. Once reached, Nginx logs the errors.
Raise system file caps.
Set the file descriptor cap in /etc/sysctl.conf.
sysctl -w fs.file-max=2097152
Raise user file caps in limits.conf.
Edit /etc/security/limits.conf and add these lines.
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535
www-data soft nofile 65535
www-data hard nofile 65535
Set systemd service caps.
Linux now runs systemd. Add file caps to each service unit. Make a custom rule for Nginx.
mkdir -p /etc/systemd/system/nginx.service.d/
cat << 'EOF' > /etc/systemd/system/nginx.service.d/limits.conf
[Service]
LimitNOFILE=65535
EOF
systemctl daemon-reload
systemctl restart nginx
The /etc/sysctl.d/99-webhost24.conf pool file for live use.
Here is a tested setup file. Save it to /etc/sysctl.d/99-webhost24.conf
on your VPS.
# /etc/sysctl.d/99-webhost24.conf
# High-concurrency web server kernel optimizations
# Socket queue backlogs
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 16384
# TIME_WAIT socket management and port ranges
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.ip_local_port_range = 1024 65535
# TCP BBR congestion control
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# TCP memory buffers (Safe for 2GB - 8GB VPS nodes)
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Keepalive intervals (Detect dead connections in 5 minutes instead of 2 hours)
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
# System file descriptor ceiling
fs.file-max = 2097152
# Protect against SYN flood attacks
net.ipv4.tcp_syncookies = 1
Apply them without a reboot.
sysctl --system
CLI checks for the new rules.
Once applied, check your setup with standard tools.
Step 1: Check that TCP BBR is active.
Run this command to see the method.
sysctl net.ipv4.tcp_congestion_control
It should return.
net.ipv4.tcp_congestion_control = bbr
Step 2: Check for listen queue drops.
Run netstat to check that your queues do not overflow.
netstat -s | grep -i listen
If you see zero queue drops, your host takes the load.
Step 3: Check active link states.
Check total live links and states with ss.
ss -s
Make sure that TIME_WAIT links stay low. Make sure they do not run
out of ports.
Step 4: Check file descriptor use.
View used file counts.
cat /proc/sys/fs/file-nr
The output shows three counts: used files, free files, and the top cap.
Step 5: Check the kernel ring buffer for errors.
Check that no SYN flood or lost packet notes show in dmesg.
dmesg | grep -E -i "syn|drop|overflow"
For broad server defense, read our VPS hosting guide.
Frequently asked questions.
How do net.core.somaxconn and net.ipv4.tcp_max_syn_backlog differ?
In short: net.ipv4.tcp_max_syn_backlog limits half open links. net.core.somaxconn limits live links that wait for your web host to take them.
When a client sends a SYN packet, it sits in the SYN queue. It waits
until the handshake ends. Then it goes into the accept queue. If the
SYN queue rule is too low, new links drop in the handshake. If
net.core.somaxconn is too low, links drop when your web workers are
full.
Does raising somaxconn use RAM when the site is idle?
In short: No. Sockets only claim RAM when real links arrive.
Setting net.core.somaxconn to 65535 raises the top queue length. It
does not take RAM for buffers. It sets a higher cap for when guests
surge.
Why was tcp_tw_recycle dropped from Linux?
In short: It breaks TCP links for guests who share one IP through NAT or phone carriers.
net.ipv4.tcp_tw_recycle used time stamps to drop old packets. When
lots of phones share one mobile IP, their time stamps do not match.
Linux thought the packets were out of order. It cut valid links. The
option was cut in Linux kernel 4.12.
How does sysctl help AI search bots?
In short: It stops lost links and cuts Time to First Byte during bot crawler visits.
Real-time AI search bots fetch pages on tight clocks. Bots like
OAI-SearchBot and PerplexityBot work this way. When a bot hits the
host in a spike, lost packets cause wait timeouts. If your host fails to
reply fast, the search bot drops your page. It cites a rival site
instead.
Final: building a strong web node.
Tune the kernel. Your web stack then handles traffic spikes. It does not drop guests. It does not stall search crawlers.
Before you push your host live, read this checklist of six points.
- Set socket queues. Raise
net.core.somaxconnandnet.ipv4.tcp_max_syn_backlogto 65535. - Align web host settings. Set
backlog=65535in your Nginx listen rules. - Turn on TCP BBR. Switch from Cubic to BBR. This protects phone guests from packet loss slowdowns.
- Clean up
TIME_WAIT. Turn onnet.ipv4.tcp_tw_reuse. Lowernet.ipv4.tcp_fin_timeoutto 15 seconds. - Set file caps. Set soft and hard file caps of 65535 in
limits.confand systemd. - Check with CLI tools. Run
sysctl --system. Check live queues withss -s.
You get fast cloud servers with fast local storage in India. You get month-to-month terms. You get clear prices for each plan. You get a full refund in 30 days. You get a daily backup kept for 7 days.
Need help with your cloud servers? Reach out to our team on WhatsApp for fast, direct help.