How to Tune Linux Performance for a Busy Server
When traffic climbs, defaults hold you back. Tune file limits, network buffers, sysctl parameters and services to squeeze more out of your VPS.
Linux defaults are conservative — tuned for compatibility across everything from a Raspberry Pi to a database server. On a busy VPS serving real traffic, a handful of adjustments can meaningfully raise throughput and cut latency. This guide covers the changes with the best effort-to-impact ratio, and how to measure whether they helped.
Measure first, tune second
Never tune blind. Establish a baseline with monitoring so you can tell whether a change actually helped. Watch load average, memory pressure, and I/O:
uptime
free -h
iostat -x 2
If the bottleneck is CPU or RAM, tuning won't beat right-sizing the plan — see how to choose VPS specs.
Raise file descriptor limits
Busy web servers and databases open thousands of connections and files. The default limit (often 1024) becomes a wall — you'll see "too many open files" errors. Check the current limit:
ulimit -n
Raise it system-wide in /etc/security/limits.conf:
* soft nofile 65535
* hard nofile 65535
For systemd services, also set it in the unit:
[Service]
LimitNOFILE=65535
Tune the network stack with sysctl
Put these in /etc/sysctl.d/99-tuning.conf and apply with sudo sysctl --system:
# Larger connection backlog for busy servers
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
# Reuse sockets in TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
# Wider ephemeral port range
net.ipv4.ip_local_port_range = 1024 65535
# Bigger network buffers
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
{{SCREENSHOT}}
Enable BBR congestion control
Google's BBR algorithm often improves throughput and latency, especially over long-distance links:
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Add those to the same sysctl file and apply. Verify:
sysctl net.ipv4.tcp_congestion_control
Get memory settings right
On a server, low swappiness keeps active data in RAM. Combine this with a properly sized swap file:
vm.swappiness = 10
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
Trim unneeded services
Every running service uses memory and is potential attack surface. List what's enabled and disable what you don't use:
systemctl list-unit-files --state=enabled
sudo systemctl disable --now snapd # example: if unused
Fewer services means more RAM for your app and a smaller footprint to secure — see essential Linux commands for more service management.
Tune the application, not just the kernel
Kernel tuning has limits — the biggest wins are usually in the app tier: worker/process counts matched to your cores, connection pooling for databases, caching, and a properly configured web server. Set worker processes to match CPU cores, and enable keep-alive and gzip. Don't forget resource limits if you run Docker.
Web server and database quick wins
The biggest real-world speedups usually come from the application tier, and two settings dominate. For your web server, match worker processes to CPU cores and enable connection keep-alive so clients aren't reconnecting constantly. In Nginx:
worker_processes auto;
worker_connections 2048;
keepalive_timeout 30;
gzip on;
worker_processes auto matches your core count automatically. Enabling gzip (or brotli) shrinks responses and cuts bandwidth noticeably for text-heavy sites.
For databases, the single highest-impact setting is the buffer/cache pool — the amount of RAM the engine uses to keep hot data in memory instead of hitting disk. On a dedicated MySQL/MariaDB box, innodb_buffer_pool_size set to roughly 60–70% of RAM often transforms performance. Add connection pooling at the app layer so you're not paying connection-setup cost on every query. These two changes routinely outperform any amount of kernel tuning.
Find the actual bottleneck before optimising
It's tempting to apply every tweak, but the disciplined approach is to identify what's actually limiting you first. Is it CPU, memory, disk I/O, or network? htop, iostat -x, and vmstat answer that in minutes. A server that's disk-bound won't benefit from network tuning; one that's memory-bound needs more RAM or lighter services, not a bigger connection backlog. Profile the application too — a single slow database query or an N+1 query pattern often causes more real-world slowness than any system setting, and no amount of sysctl tuning fixes bad application code. Measure, change one thing, measure again: that loop, backed by monitoring, is how you tune with confidence instead of cargo-culting settings that may not help your particular workload.
FAQ
Will sysctl tuning make a slow server fast?
It removes artificial bottlenecks, but it can't add CPU or RAM you don't have. If you're consistently resource-bound, resize the plan — tuning is for using what you have efficiently.
Do these changes persist across reboots?
Only if you write them to config files (/etc/sysctl.d/, /etc/security/limits.conf, systemd units). Values set with sysctl -w at the command line are lost on reboot.
Is BBR safe to enable?
Yes, BBR is stable and widely used. It typically helps throughput and latency, particularly on higher-latency connections. Test with your own traffic to confirm.
What's the most common performance limit on a small VPS?
Memory. When RAM fills, the server swaps and everything slows. Watch memory/swap first, then file limits and network settings.
A sensible tuning order
Approach performance work methodically so you spend effort where it helps:
- Measure and baseline with
htop,iostat -x 2,vmstat, andfree -h— identify whether you're CPU, memory, disk, or network bound. - Raise file descriptor limits if you see "too many open files" (
nofile 65535). - Tune the network stack via
/etc/sysctl.d/— backlog, port range, buffers, and BBR. - Get memory settings right — low swappiness plus an appropriate swap file.
- Trim unneeded services to free RAM and shrink attack surface.
- Tune the application tier — worker counts matched to cores, gzip, the database buffer pool, and connection pooling.
- Re-measure and change one thing at a time.
The recurring lesson is that tuning removes artificial bottlenecks but can't manufacture resources you don't have. If you're consistently CPU- or memory-bound after this, the honest fix is a bigger plan, not another sysctl tweak. And often the largest single win isn't a system setting at all — it's a slow query or inefficient code path that profiling reveals. Measure, change, measure again, and you'll tune with confidence instead of guesswork.
Smart tuning gets more out of every plan — but pair it with the right specs. Explore fast NVMe VPS plans and the best value VPS options.