Where parameters live
Each parameter is a file under /proc/sys/:
/proc/sys/net/ipv4/ip_forward ↔ net.ipv4.ip_forward
/proc/sys/net/ipv4/tcp_congestion_control ↔ net.ipv4.tcp_congestion_control
/proc/sys/vm/swappiness ↔ vm.swappiness
/proc/sys/kernel/pid_max ↔ kernel.pid_max
Dots in the sysctl name correspond to slashes in the path. Reading or writing the file is equivalent to calling sysctl.
Basic commands
sysctl -a # all parameters (thousands)
sysctl -a 2>/dev/null | grep ^net.ipv4.tcp # filter by subsystem
sysctl net.ipv4.ip_forward # read one parameter
sysctl -n net.ipv4.ip_forward # -n: value only, no name
sudo sysctl -w net.ipv4.ip_forward=1 # set (until reboot)
Persistent changes
-w survives only until the next reboot. To make a change permanent:
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-router.conf
sudo sysctl --system # apply all .conf files right now
Files in /etc/sysctl.d/ are read in lexicographic order. A numeric prefix (99- or 10-) controls priority.
Common subsystems
- net.ipv4.tcp_*: all TCP tunables (congestion control, keepalive, windows)
- net.ipv4.ip_forward: turn the machine into a router (ip-forwarding)
- net.core.*: general network buffers and qdisc defaults
- net.netfilter.nf_conntrack_max: connection tracking table size
- vm.swappiness: how aggressively the kernel uses swap (0-100)
- vm.overcommit_memory: memory overcommit strategy
- fs.file-max: global open file descriptor limit
- kernel.pid_max: maximum PID (default 32768 or 4M)
Inside a container
In Docker, /proc/sys is mounted read-only. sysctl -w fails with EPERM unless the container runs with --privileged or the required capability (SYS_ADMIN plus the correct mount). Some parameters are per-namespace (network sysctls); others are global and the host does not expose them to containers.
Backup before changes
sysctl -a > /tmp/sysctl-backup-$(date +%F).txt 2>/dev/null
If tuning breaks something, compare with diff against the snapshot.