Operations 34 min read

20 Must‑Change Linux Kernel Parameters for Production Environments

This article presents a practical checklist of 20 Linux kernel parameters—grouped by network, memory, process, and filesystem settings—explaining their default values, typical failure symptoms, step‑by‑step tuning commands, verification methods, and rollback procedures to ensure production systems such as web servers, databases, caches, and containers run without kernel‑level bottlenecks.

Raymond Ops
Raymond Ops
Raymond Ops
20 Must‑Change Linux Kernel Parameters for Production Environments

Background and Scope

Linux distributions ship with conservative default kernel parameters that work for low‑load, generic workloads. In production environments—high‑concurrency web services, APIs, databases, caches, message queues, or container platforms—these defaults quickly become performance bottlenecks.

Preparation – Backup and Rollback

All tunable parameters reside under /proc/sys/ and are modified with the sysctl command. Before making any changes, back up the current values:

# Backup all kernel parameters to a file
sysctl -a > /backup/sysctl_backup_$(date +%Y%m%d_%H%M%S).conf

To roll back, restore the backup:

# Restore all parameters (use with caution)
sysctl -p /backup/sysctl_backup_20260521_143000.conf

Permanent changes are written to /etc/sysctl.conf or a file under /etc/sysctl.d/ (e.g., /etc/sysctl.d/99‑custom.conf) and applied with sysctl -p.

Category 1: Network Parameters

1. net.core.somaxconn – Max listen queue length

Principle: Limits the size of the full‑connection (accept) queue after a SYN is received. The kernel value and the application’s listen() backlog are compared; the smaller one wins.

Default: 128 on most distributions.

Symptoms: Nginx errors such as connect() failed (99: Cannot assign requested address) or upstream 502 responses due to a full accept queue.

Tuning:

# Temporary (lost after reboot)
sysctl -w net.core.somaxconn=65535
# Permanent
echo "net.core.somaxconn = 65535" >> /etc/sysctl.d/99‑custom.conf
sysctl -p /etc/sysctl.d/99‑custom.conf

Application side: In Nginx set listen 80 backlog=65535;; MySQL’s back_log should match.

Verification: ss -ltn sport=:80 and sysctl net.core.somaxconn.

2. net.core.netdev_max_backlog – NIC receive queue length

Principle: When the NIC receives packets faster than the kernel can process them, excess packets are placed in this backlog queue.

Default: 1000 (varies by distro).

Symptoms: Increasing RX errors, RX drops, or RX overruns shown by netstat -i or ifconfig, plus rising latency.

Tuning:

sysctl -w net.core.netdev_max_backlog=65535
echo "net.core.netdev_max_backlog = 65535" >> /etc/sysctl.d/99‑custom.conf

Verification: cat /proc/net/softnet_stat (third column shows drops).

3. net.ipv4.tcp_max_syn_backlog – Half‑open (SYN) queue length

Principle: Controls the size of the SYN queue during the TCP three‑way handshake. If the queue fills, new SYN packets are dropped, causing client time‑outs.

Default: 128 (CentOS 6) or 1280 on newer kernels.

Symptoms: Massive SYN drops, visible as SYNs to LISTEN sockets dropped in netstat -s.

Tuning:

sysctl -w net.ipv4.tcp_max_syn_backlog=65535
echo "net.ipv4.tcp_max_syn_backlog = 65535" >> /etc/sysctl.d/99‑custom.conf

Note: Since Linux 4.3 this value is also limited by net.core.somaxconn.

4. net.ipv4.ip_local_port_range – Available client ports

Principle: Defines the range of ephemeral ports for outbound connections. Default is 32768‑60999 (~28 k ports).

Symptoms: “cannot assign requested address” errors when the range is exhausted, especially for proxies, crawlers, or high‑concurrency clients.

Tuning:

sysctl -w net.ipv4.ip_local_port_range="1024 65535"
echo "net.ipv4.ip_local_port_range = 1024 65535" >> /etc/sysctl.d/99‑custom.conf

Risk: Ports below 1024 are reserved; ensure no service relies on the original lower range.

5. net.ipv4.tcp_fin_timeout – FIN_WAIT_2 timeout

Principle: Controls how long a socket stays in FIN_WAIT_2 before being reclaimed (default 60 s). Shortening speeds up port reuse.

Default: 60.

Symptoms: Large numbers of TIME_WAIT sockets, port exhaustion, or premature connection closure in long‑lived transfers.

Tuning:

sysctl -w net.ipv4.tcp_fin_timeout=15
echo "net.ipv4.tcp_fin_timeout = 15" >> /etc/sysctl.d/99‑custom.conf

Risk: Setting too low may abort active transfers.

6. net.ipv4.tcp_tw_reuse – TIME_WAIT reuse (client side)

Principle: Allows the kernel to reuse sockets in TIME_WAIT for new connections when safe.

Default: 0 or 1 depending on distro.

Symptoms: Accumulated TIME_WAIT sockets and “cannot assign requested address”.

Tuning:

sysctl -w net.ipv4.tcp_tw_reuse=1
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.d/99‑custom.conf

7. net.ipv4.tcp_tw_recycle – TIME_WAIT recycle (server side)

Principle: Quickly recycles TIME_WAIT sockets but breaks NAT and cloud environments.

Default: 0 (recommended to keep disabled).

Tuning: Ensure it stays 0; enable only in isolated LANs.

8. net.core.rmem_max / net.core.wmem_max – Max socket buffers

Principle: Upper limits for receive and send buffers. Larger values help high‑throughput NICs (e.g., 10 GbE).

Default: Varies; often insufficient for 10 GbE.

Tuning:

sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
echo "net.core.rmem_max = 16777216" >> /etc/sysctl.d/99‑custom.conf
echo "net.core.wmem_max = 16777216" >> /etc/sysctl.d/99‑custom.conf

Verification: cat /proc/sys/net/core/rmem_max and wmem_max.

Category 2: Memory and File‑Handle Parameters

10. fs.file-max and fs.nr_open – System‑wide and per‑process file descriptor limits

Principle: fs.file-max caps total open files; fs.nr_open caps per‑process descriptors.

Default: Several million for fs.file-max, 1 048 576 for fs.nr_open.

Symptoms: “Too many open files” errors, high counts in /proc/sys/fs/file-nr.

Tuning:

sysctl -w fs.file-max=2097152
echo "fs.file-max = 2097152" >> /etc/sysctl.d/99‑custom.conf
# Adjust per‑process limits in /etc/security/limits.conf
# Example:
# * soft nofile 1048576
# * hard nofile 1048576

11. vm.swappiness – Swap aggressiveness

Principle: Controls how readily the kernel swaps out idle pages (0‑100). Lower values keep memory in RAM longer.

Default: 60.

Symptoms: Unexpected swap usage, OOM kills, database buffer pool eviction.

Tuning:

sysctl -w vm.swappiness=10
echo "vm.swappiness = 10" >> /etc/sysctl.d/99‑custom.conf

Note: Values 10‑30 are typical for production servers.

12. vm.dirty_background_ratio & vm.dirty_ratio – Dirty‑page write‑back thresholds

Principle: When the percentage of dirty pages reaches vm.dirty_background_ratio, the kernel starts background flushing; reaching vm.dirty_ratio forces synchronous write‑back.

Defaults: 10 (background) / 20 (ratio).

Symptoms: Sudden stalls during heavy writes, delayed DB commits.

Tuning (DB‑friendly):

sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_ratio=10
echo "vm.dirty_background_ratio = 5" >> /etc/sysctl.d/99‑custom.conf
echo "vm.dirty_ratio = 10" >> /etc/sysctl.d/99‑custom.conf

13. vm.vfs_cache_pressure – Page‑cache vs. inode/dentry reclaim

Principle: Higher values cause the kernel to reclaim VFS caches more aggressively.

Default: 100.

Symptoms: Database performance drop after reboot due to cache eviction.

Tuning:

sysctl -w vm.vfs_cache_pressure=50
echo "vm.vfs_cache_pressure = 50" >> /etc/sysctl.d/99‑custom.conf

14. kernel.shmmax & kernel.shmall – Shared‑memory limits

Principle: shmmax is the maximum size of a single shared‑memory segment; shmall is the total number of shared‑memory pages.

Typical values for large DBs: shmmax=68719476736 (64 GB) and shmall=16777216 (64 GB / 4096‑byte pages).

Tuning:

sysctl -w kernel.shmmax=68719476736
sysctl -w kernel.shmall=16777216
echo "kernel.shmmax = 68719476736" >> /etc/sysctl.d/99‑custom.conf
echo "kernel.shmall = 16777216" >> /etc/sysctl.d/99‑custom.conf

15. kernel.msgmnb & kernel.msgmni – System V message queue limits

Principle: msgmnb sets the max size of a single queue; msgmni sets the max number of queues.

Typical tuning:

sysctl -w kernel.msgmnb=65536
sysctl -w kernel.msgmni=1024
echo "kernel.msgmnb = 65536" >> /etc/sysctl.d/99‑custom.conf
echo "kernel.msgmni = 1024" >> /etc/sysctl.d/99‑custom.conf

Category 3: Process and Signal Parameters

17. kernel.pid_max – Maximum PID

Principle: Upper bound for process IDs. When reached, IDs wrap and may be reused.

Default: 32768 (32‑bit) or 4194304 (64‑bit).

Symptoms: High‑process workloads (many containers, Java threads) see PID values near the limit.

Tuning:

sysctl -w kernel.pid_max=4194304
echo "kernel.pid_max = 4194304" >> /etc/sysctl.d/99‑custom.conf

18. kernel.threads-max – Maximum number of threads

Principle: System‑wide thread limit, usually twice pid_max.

Symptoms: Errors like fork: Resource temporarily unavailable or kernel:EDF: request for more threads.

Tuning:

sysctl -w kernel.threads-max=4194304
echo "kernel.threads-max = 4194304" >> /etc/sysctl.d/99‑custom.conf
# Also raise per‑user limits in /etc/security/limits.conf
# * soft nproc 4194304
# * hard nproc 4194304

19. kernel.sem – System V semaphore limits

Principle: Four values (SEMMSL, SEMMNS, SEMOPM, SEMMNI) control semaphore resources used by databases and legacy middleware.

Typical safe setting: 250 32000 100 256.

Tuning:

sysctl -w kernel.sem="250 32000 100 256"
echo "kernel.sem = 250 32000 100 256" >> /etc/sysctl.d/99‑custom.conf

Category 4: Disk and Filesystem Parameters

20. net.ipv4.icmp_echo_ignore_broadcasts & net.ipv4.icmp_ratelimit – ICMP hardening

Principle: Prevents the host from responding to broadcast/multicast pings (Smurf attacks) and limits ICMP reply rate.

Tuning:

sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1
sysctl -w net.ipv4.icmp_ratelimit=1000
echo "net.ipv4.icmp_echo_ignore_broadcasts = 1" >> /etc/sysctl.d/99‑custom.conf
echo "net.ipv4.icmp_ratelimit = 1000" >> /etc/sysctl.d/99‑custom.conf

Note: icmp_ratelimit is measured in jiffies; 1000 is a permissive value.

Production‑grade Operational Practices

Permanent Configuration File

Collect all tuned parameters in a single file, e.g. /etc/sysctl.d/99‑custom.conf:

# Network
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Memory & file handles
fs.file-max = 2097152
vm.swappiness = 10
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
vm.vfs_cache_pressure = 50
kernel.shmmax = 68719476736
kernel.shmall = 16777216
kernel.msgmnb = 65536
kernel.msgmni = 1024
net.core.rmem_default = 262144
net.core.wmem_default = 262144
# Process & signals
kernel.pid_max = 4194304
kernel.threads-max = 4194304
kernel.sem = 250 32000 100 256
# ICMP security
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ratelimit = 1000

Apply with:

sysctl -p /etc/sysctl.d/99‑custom.conf

Verification Script

A simple Bash script checks that each parameter matches the expected value:

#!/bin/bash
EXPECTED=(
  "net.core.somaxconn=65535"
  "net.core.netdev_max_backlog=65535"
  "net.ipv4.tcp_max_syn_backlog=65535"
  "fs.file-max=2097152"
  "vm.swappiness=10"
  "kernel.pid_max=4194304"
)
for item in "${EXPECTED[@]}"; do
  param=${item%%=*}
  expected=${item##*=}
  actual=$(sysctl -n "$param" 2>/dev/null)
  if [[ "$actual" == "$expected" ]]; then
    echo "[OK] $param = $actual"
  else
    echo "[FAIL] $param: expected $expected, got $actual"
  fi
done

Step‑by‑Step Rollout

Apply changes temporarily on a single test host with sysctl -w and monitor for 24‑48 hours.

If stable, add the settings to /etc/sysctl.d/99‑custom.conf.

Use configuration management tools (Ansible, Salt, etc.) to push the file to the fleet.

Perform a rolling restart of dependent services to avoid simultaneous downtime.

Rollback Procedure

If a change causes issues, revert the specific parameter using the backup file or by re‑applying the original value:

# Roll back a single key
sysctl -w net.core.somaxconn=128
# Full rollback
sysctl -p /backup/sysctl_backup_20260521_143000.conf

Always keep the backup created before any modification.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PerformancekernelnetworkLinuxmemorysysctltuning
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.