How to Tune Kernel Parameters on Linux with sysctl
A complete walkthrough reading, changing, and persisting kernel runtime parameters — with a few of the most commonly tuned examples explained, not just listed.
sysctl is the standard interface for reading and changing Linux kernel parameters at runtime — the same /proc/sys tree covered elsewhere on this blog, accessed through a purpose-built command instead of raw file reads and writes.
Step 1: view a specific parameter’s current value
sysctl net.ipv4.ip_forward
Every sysctl parameter name maps directly to a path under /proc/sys — net.ipv4.ip_forward corresponds to /proc/sys/net/ipv4/ip_forward, with dots replacing slashes.
Step 2: list every currently available parameter
sysctl -a
This is a long list — hundreds of tunable parameters across networking, virtual memory, kernel scheduling, and more — worth knowing exists even if you only ever look up specific ones you need.
Step 3: change a parameter temporarily (until reboot)
sudo sysctl -w net.ipv4.ip_forward=1
Changes made this way take effect immediately but don’t survive a reboot — useful for testing a change before committing to it permanently.
Step 4: persist a change permanently
# /etc/sysctl.conf, or a file in /etc/sysctl.d/
net.ipv4.ip_forward = 1
sudo sysctl -p
sysctl -p reloads settings from the configuration file immediately, without requiring a reboot to apply a persisted change.
Step 5: a commonly tuned example — increasing the file descriptor ceiling
fs.file-max = 2097152
Relevant when running services that need far more open file descriptors than the conservative default supports — see fixing ‘too many open files’ errors for the full troubleshooting path this setting is part of.
Step 6: a commonly tuned example — adjusting swap aggressiveness
vm.swappiness = 10
vm.swappiness (0–100) controls how aggressively the kernel prefers swapping out memory versus reclaiming page cache — lowering it from the default (typically 60) is a common tweak on systems with plenty of RAM where any swapping at all causes a noticeable performance hit.
Step 7: a commonly tuned example — network buffer sizes for high-throughput workloads
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
Relevant for high-bandwidth or high-latency network connections, where the default socket buffer sizes limit achievable throughput regardless of available bandwidth.
Step 8: verify a change actually took effect
sysctl net.core.rmem_max
cat /proc/sys/net/core/rmem_max
Both commands should agree — sysctl is just a friendlier interface over the same underlying /proc/sys values.
Why understanding what you’re changing matters more than copying a tuning guide
Sysctl parameters exist because the kernel’s defaults represent a reasonable general-purpose tradeoff — changing them shifts that tradeoff in a specific direction for a specific workload, not a universal improvement. Copying a list of “performance tuning” sysctl values from a guide without understanding what each one actually trades off is how systems end up with settings tuned for a completely different workload than the one actually running on them — worth understanding the specific problem each parameter addresses before changing it, rather than treating tuning guides as universally applicable defaults.