Skip to content

Linux Kernel Parameters (sysctl) Tuning Guide

DodaTech Updated 2026-06-24 5 min read

In this tutorial, you'll learn about Linux Kernel Parameters (sysctl) Tuning Guide. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Linux kernel parameters control how the kernel manages memory, networking, filesystems, and security. The sysctl interface lets you read and modify these parameters at runtime without rebooting.

Hook

Kernel tuning optimizes a Linux system for its workload — high-traffic web server, database, file server, or container host. You will learn to read, modify, and persist sysctl parameters across key subsystems. Durga Antivirus Pro tunes kernel parameters on its scanning nodes to handle high file I/O and connection rates.

Why Kernel Tuning Matters

Default kernel settings are conservative — optimized for general-purpose use on minimal hardware. Production workloads require tuning: a database server needs different memory management than a web server, which needs different network settings than a file server. Changing a single parameter can improve throughput by 5x.

Kernel Parameters Overview

flowchart LR
  A[sysctl] --> B[net - Network Stack]
  A --> C[vm - Virtual Memory]
  A --> D[kernel - Core Kernel]
  A --> E[fs - Filesystem]
  B --> F[/proc/sys/net/]
  C --> G[/proc/sys/vm/]
  D --> H[/proc/sys/kernel/]
  E --> I[/proc/sys/fs/]

Viewing Parameters

# List all parameters
sysctl -a

# Read specific parameters
sysctl net.ipv4.tcp_rmem
sysctl vm.swappiness
sysctl fs.file-max

# Read from /proc directly
cat /proc/sys/vm/swappiness

Modifying Parameters at Runtime

# Set a parameter (immediate, not persistent)
sudo sysctl -w vm.swappiness=10
sudo sysctl -w net.ipv4.tcp_syncookies=1

# Multiple parameters at once
sudo sysctl -w \
  net.core.rmem_max=16777216 \
  net.core.wmem_max=16777216 \
  vm.dirty_ratio=30

Making Changes Persistent

Add entries to /etc/sysctl.conf or a file in /etc/sysctl.d/:

# Create a custom config file
sudo tee /etc/sysctl.d/99-custom.conf << 'EOF'
# Network tuning
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.tcp_congestion_control = bbr

# Memory management
vm.swappiness = 10
vm.dirty_ratio = 30
vm.dirty_background_ratio = 5
vm.vfs_cache_pressure = 50

# Security
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
EOF

# Apply
sudo sysctl --system

Network Stack Tuning

TCP Buffer Sizes

# min default max (bytes)
net.ipv4.tcp_rmem = 4096 131072 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

Connection Handling

net.core.somaxconn = 1024           # Max listen backlog
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_fastopen = 3           # Enable TFO (client+server)
net.ipv4.tcp_tw_reuse = 1           # Reuse TIME_WAIT sockets
net.ipv4.tcp_fin_timeout = 15       # Faster FIN cleanup

BBR Congestion Control

BBR improves throughput on high-latency links:

net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq

Virtual Memory (VM) Tuning

Swappiness

Controls how aggressively the kernel swaps:

vm.swappiness = 10     # 0-100. Lower = swap less (servers)
  • 0: swap only when out of memory
  • 10-30: recommended for most servers
  • 60: default
  • 100: swap aggressively

Dirty Page Management

vm.dirty_ratio = 30           # Max % of RAM dirty before blocking writes
vm.dirty_background_ratio = 5 # Start background writeback at this %
vm.dirty_expire_centisecs = 3000  # 30s before dirty pages are expired

OOM Settings

vm.overcommit_memory = 0      # Heuristic overcommit (default)
vm.overcommit_ratio = 50      # % of RAM for overcommit
vm.panic_on_oom = 0           # Don't panic, kill OOM process

Filesystem and File Handle Tuning

fs.file-max = 2097152                    # Max open files system-wide
fs.nr_open = 2097152                     # Max open files per process
fs.inotify.max_user_watches = 524288     # For file watchers (IDEs, webpack)
fs.aio-max-nr = 1048576                  # Async I/O requests
# Restrict kernel pointer visibility
kernel.kptr_restrict = 2     # 0=all, 1=root only, 2=disabled for all
kernel.dmesg_restrict = 1    # Prevent non-root from seeing kernel log

# Network hardening
net.ipv4.conf.all.rp_filter = 1     # Reverse path filtering
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# Disable ICMP redirects
net.ipv4.conf.all.accept_source_route = 0

Applying Tuning Profiles

Create profiles for different workloads:

# Database server profile
sudo tee /etc/sysctl.d/90-database.conf << 'EOF'
vm.swappiness = 1
vm.dirty_ratio = 10
vm.dirty_background_ratio = 3
vm.overcommit_memory = 2
vm.overcommit_ratio = 95
kernel.shmmax = 68719476736
kernel.shmall = 16777216
EOF

Verifying Changes

# Check current values
sysctl vm.swappiness net.ipv4.tcp_congestion_control

# Check boot-time persistence
sudo sysctl --system | grep -E "swappiness|congestion"

Expected output:

$ sysctl vm.swappiness net.ipv4.tcp_congestion_control
vm.swappiness = 10
net.ipv4.tcp_congestion_control = bbr

Common Errors

1. "sysctl: permission denied on key"

Some parameters require specific kernel features or are read-only. Check ls -l /proc/sys/net/ipv4/tcp_syncookies — 0644 means writable.

2. Parameter Not Found After Reboot

The config file may have wrong syntax. Run sudo sysctl --system and check for errors. Each line must be key = value with no spaces around =.

3. Network Performance Degradation

Aggressive buffer sizes can waste memory. Start with moderate values and benchmark. Monitors with ss -m to check socket memory usage.

4. OOM Kills Despite Free Memory

vm.overcommit_memory=2 with low overcommit_ratio may reject allocations. Set to 0 (heuristic) for most workloads.

5. BBR Not Available

BBR requires kernel 4.9+. Check modprobe tcp_bbr and sysctl net.ipv4.tcp_available_congestion_control.

6. File-max Limit Hit

Services report "Too many open files". Increase fs.file-max and also ulimit -n per Process. Check /etc/security/limits.conf.

7. Permission Denied on /proc/sys Modification

Container environments restrict sysctl writes. Use --sysctl with Docker or set kernel.sysctl_allow in Kubernetes security contexts.

Practice Questions

1. How do you make a sysctl change permanent? Add the parameter to /etc/sysctl.d/*.conf and run sudo sysctl --system. The parameter will apply at boot.

2. What does vm.swappiness = 10 do? Tells the kernel to avoid swapping until memory is 90% full. Lower values are better for servers.

3. What is BBR and why use it? BBR (Bottleneck Bandwidth and Round-trip) is a TCP congestion control algorithm that improves throughput up to 5-10x on high-latency links compared to CUBIC.

4. How do you check available TCP congestion control algorithms? sysctl net.ipv4.tcp_available_congestion_control

5. Challenge: A web server experiences SYN flood attacks, slow connections, and port exhaustion. Tune the kernel parameters to mitigate all three. Answer: Enable syncookies (net.ipv4.tcp_syncookies=1), increase backlog (net.core.somaxconn=4096, net.ipv4.tcp_max_syn_backlog=8192), enable fast recycling (net.ipv4.tcp_tw_reuse=1, net.ipv4.tcp_fin_timeout=15), and increase ephemeral port range (net.ipv4.ip_local_port_range="1024 65535").

Mini Project: System Tuning Diagnostic Script

#!/bin/bash
# sysctl_diag.sh — Report key kernel parameters with recommendations
# Usage: ./sysctl_diag.sh

echo "=== Kernel Tuning Report ==="
echo "Date: $(date)"
echo

params=(
  "vm.swappiness:10:Server (low swap)"
  "net.ipv4.tcp_congestion_control:bbr:High perf"
  "net.core.rmem_max:16777216:16MB recv"
  "fs.file-max:2097152:2M files"
  "kernel.kptr_restrict:2:Security"
)

for entry in "${params[@]}"; do
    IFS=":" read -r key recommended desc <<< "$entry"
    current=$(sysctl -n "$key" 2>/dev/null || echo "N/A")
    echo "$key = $current (recommended: $recommended - $desc)"
done

echo
total_mem=$(grep MemTotal /proc/meminfo | awk '{print $2}')
echo "Total memory: $((total_mem / 1024 / 1024)) GB"
echo "Dirty ratio limit: $((total_mem * $(sysctl -n vm.dirty_ratio) / 100 / 1024 / 1024)) MB"

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-24.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro