Tuning without measuring is guessing. Before changing kernel settings, find out what’s actually limiting the server: CPU, memory, disk or network. Then apply the changes below that match the bottleneck. Everything here applies to Debian 12 and 13 (and most of it to Ubuntu).
1. Find the bottleneck
apt install -y sysstat htop iotop
uptime # load averages vs number of CPUs (nproc)
htop # per-process CPU and memory
vmstat 1 10 # 'wa' = I/O wait, 'si/so' = swapping
iostat -xz 1 5 # disk utilization (%util) and latency (await)
ss -s # connection counts
| What you see | Likely bottleneck |
|---|---|
Load above CPU count, high us/sy CPU |
CPU — optimize the application or add cores |
si/so not zero, little free memory |
RAM — reduce workers or add memory |
High wa, disk %util near 100% |
Disk I/O — caching, fewer writes, faster storage |
Many connections in TIME-WAIT or errors in logs about “too many open files” |
Network / limits — tune below |
2. Raise open file limits
Every connection uses a file descriptor. Defaults are often too low for busy web servers.
For services managed by systemd, set the limit in a drop-in:
systemctl edit nginx
[Service]
LimitNOFILE=65535
And in /etc/nginx/nginx.conf: worker_rlimit_nofile 65535;. Restart the service afterwards.
3. Kernel network settings
Create /etc/sysctl.d/90-tuning.conf:
# Larger accept queue for bursts of new connections
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
# More local ports for outgoing connections (proxies, APIs)
net.ipv4.ip_local_port_range = 10240 65535
# Reuse TIME-WAIT sockets for new outgoing connections
net.ipv4.tcp_tw_reuse = 1
# BBR congestion control: better throughput on long-distance links
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Apply with sysctl --system. Check BBR is active: sysctl net.ipv4.tcp_congestion_control.
BBR is especially useful when your users are far from the server, for example visitors in Asia reaching a US server.
4. Memory and swap
-
Keep a modest swap file as a safety net (see swap file vs swap partition).
-
Lower swappiness so the kernel prefers RAM for applications:
# /etc/sysctl.d/90-tuning.conf vm.swappiness = 10 -
Size worker pools (PHP-FPM, application workers) to fit in RAM. Swapping under load is far worse than queueing a few requests.
5. Disk I/O
- Mount data filesystems with
noatimeto avoid a write on every read (/etc/fstaboptions:defaults,noatime). - Move logs that are written heavily to buffered logging (Nginx:
access_log /var/log/nginx/access.log combined buffer=64k flush=5s;) or disable access logs for static files. - Check the I/O scheduler: on virtual disks,
noneormq-deadlineis usually best —cat /sys/block/vda/queue/scheduler.
Read more in Linux disk performance and Linux disk caching.
6. Web server
For Nginx:
worker_processes auto;
events { worker_connections 4096; multi_accept on; }
http {
sendfile on;
tcp_nopush on;
keepalive_timeout 30;
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
open_file_cache max=10000 inactive=60s;
}
Serve static files with long cache headers and cache dynamic pages where possible — a page served from cache costs almost nothing.
7. Database
For MariaDB/MySQL, the most important setting is the InnoDB buffer pool — make it large enough to hold your working data set (often 50–70% of RAM on a dedicated database server, less if the web server runs on the same machine):
[mysqld]
innodb_buffer_pool_size = 2G
Enable the slow query log to find queries that need indexes:
slow_query_log = 1
long_query_time = 1
8. Keep it updated and monitored
- Install security updates automatically — see unattended upgrades.
- Monitor CPU, RAM, disk and response times over time (Netdata, Prometheus + Grafana, or a hosted monitor) so you see trends before users do.
When tuning isn’t enough
If the server is consistently at its limits after tuning, it’s time to scale up: more vCPUs and RAM, or split the database onto its own server. Our Debian VPS plans can be upgraded by ticket without reinstalling. See also Linux server performance for application-level techniques.