Skip to main content
RunBook Academy

LinuxX · Kernel Managementsysctl

sysctl — runtime kernel tuning

Intermediate⏱ ~10 minbashsysctlsystemd-sysctl

What you'll learn

  • Read current sysctl values
  • Set sysctl values at runtime and persistently
  • Identify the most production-relevant sysctl parameters
  • Troubleshoot sysctl values that did not persist

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

The kernel exposes hundreds of tunable parameters through the /proc/sys/ filesystem. Reading and setting these parameters is how a sysadmin tunes the kernel at runtime — no recompile, no reboot, just a sysctl call.

Reading sysctl values

Read-only / Safesysctl
$ sysctl net.ipv4.ip_forward; sysctl -a | head -10
net.ipv4.ip_forward = 0
abi.vsyscall32 = 1
debug.exception-trace = 1
dev.hpet.max-user-freq = 64
dev.parport.default = 0x3bc
...

Illustrative output

The sysctl namespace mirrors the /proc/sys/ directory:

net.ipv4.ip_forward    =   /proc/sys/net/ipv4/ip_forward
vm.swappiness          =   /proc/sys/vm/swappiness
kernel.pid_max         =   /proc/sys/kernel/pid_max
Read-only / Safesysctl security-relevant
$ sysctl net.ipv4.tcp_syncookies net.ipv4.conf.all.rp_filter net.core.somaxconn vm.swappiness
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.core.somaxconn = 4096
vm.swappiness = 60

Illustrative output

Setting at runtime

Configuration changeset sysctl
$ sudo sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

Illustrative output

Persisting changes

There are three places to put persistent sysctl values:

  1. /etc/sysctl.conf — the legacy single-file configuration.
  2. /etc/sysctl.d/*.conf — the modern modular configuration. Each file is read in lexical order.
  3. Runtime drop-ins via systemd-sysctl for transient values.
Configuration changepersist sysctl
$ sudo tee /etc/sysctl.d/99-production.conf >/dev/null <<'EOF'
# Production sysctl overrides

# Network: enable IP forwarding (for router/gateway hosts)
net.ipv4.ip_forward = 1

# TCP: harden against SYN flood
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 4096

# Reverse-path filtering
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Kernel: allow more PIDs for high-forking services
kernel.pid_max = 4194304

# VM: tune swappiness for database hosts
vm.swappiness = 10
EOF
sudo sysctl --system

Production-relevant sysctl parameters

SubsystemParameterMeaningProduction value
net.ipv4ip_forwardIP forwarding1 for routers/gateways, 0 otherwise
net.ipv4tcp_syncookiesSYN flood protection1 (enable)
net.ipv4conf.all.rp_filterReverse-path filtering1 (enable)
net.ipv4conf.all.accept_source_routeSource-routed packets0 (disable)
net.ipv4conf.all.accept_redirectsAccept ICMP redirects0 everywhere, routers included
net.ipv4conf.all.secure_redirectsAccept redirects from default gateways only0 — narrower than accepting all, still unauthenticated
net.ipv4conf.all.send_redirectsEmit ICMP redirects0 on hosts; 1 only on a router that is deliberately the redirect authority for its segment
net.ipv4icmp_echo_ignore_broadcastsIgnore pings to broadcast1 (smurf protection)
net.ipv4tcp_max_syn_backlogSYN backlog4096+ for high-traffic
net.coresomaxconnlisten() backlog4096+ for high-traffic
kernelpid_maxMaximum PID4194304 for high-forking
kernelthreads-maxMaximum threadspid_max × 4 typically
vmswappinessSwap preference10-60 depending on workload
fsfile-maxMaximum open filesmatches systemd LimitNOFILE
fsnr_openMaximum per-process open filesmatches systemd LimitNOFILE
Read-only / Safesystemd-sysctl
$ systemd-sysctl
Aug  9 12:00:01 host systemd-sysctl[1234]: Successfully applied sysctl: net.ipv4.ip_forward=1
Aug  9 12:00:01 host systemd-sysctl[1234]: Successfully applied sysctl: kernel.pid_max=4194304
...

Illustrative output

Investigating “sysctl did not persist”

Read-only / Safeverify sysctl
$ sudo sysctl net.ipv4.ip_forward; cat /proc/sys/net/ipv4/ip_forward; sudo sysctl --system 2>&1 | head
...

Illustrative output

  1. Read the current value before changing: sysctl KEY
  2. Set at runtime to test: sysctl -w KEY=VALUE
  3. Persist in /etc/sysctl.d/ with a high-priority filename (90-, 99-)
  4. **Apply with sysctl --system** and verify the value is now what you want
  5. Add the file to version control (git, etckeeper, configuration management)
  6. Document the rationale for non-default values; future operators need to know why

Knowledge check

Knowledge check · 3 questions

  1. Q1. Which is the correct way to persist a sysctl change across reboots?

  2. Q2. `net.ipv4.ip_forward = 1` should be set on every Linux host.

  3. Q3. Which of the following are correct sysctl practices? Select all that apply.

Passing score: 75%. Answers are checked in this browser.