Learn to view, modify, and persist Linux kernel parameters using sysctl for system performance tuning. Configure network, memory, and security settings safely with temporary and permanent changes.
Prerequisites
- Root or sudo access
- Basic command line knowledge
- Understanding of system administration concepts
What this solves
The Linux kernel exposes hundreds of tunable parameters through the sysctl interface, allowing you to optimize system behavior for specific workloads. You need this when running high-traffic web servers, databases, or applications that require specific network buffer sizes, memory management settings, or security configurations. This tutorial shows you how to safely view current parameters, test changes temporarily, and make permanent optimizations.
Understanding sysctl and kernel parameters
The sysctl (system control) interface provides runtime access to kernel parameters stored in the /proc/sys virtual filesystem. These parameters control everything from network stack behavior to memory management policies. Parameters are organized in a hierarchical structure using dots as separators, like net.core.rmem_max or vm.swappiness.
Changes made with the sysctl command take effect immediately but are lost on reboot unless saved to configuration files. This makes it safe to test optimizations before committing them permanently.
Step-by-step configuration
Install sysctl tools
Most distributions include sysctl by default, but ensure you have the complete procps package for all utilities.
sudo apt update
sudo apt install -y procps
View all current kernel parameters
Display all available sysctl parameters and their current values. This shows you the complete system state.
sysctl -a | head -20
sysctl -a | wc -l
Search for specific parameters
Find parameters related to specific subsystems like networking, memory management, or security.
# Network-related parameters
sysctl -a | grep -i net.core
Memory management parameters
sysctl -a | grep -i vm
Security parameters
sysctl -a | grep -i kernel
View individual parameter values
Check specific kernel parameters to understand current system configuration before making changes.
# View network buffer sizes
sysctl net.core.rmem_max
sysctl net.core.wmem_max
View memory management settings
sysctl vm.swappiness
sysctl vm.dirty_ratio
View security settings
sysctl kernel.dmesg_restrict
Make temporary parameter changes
Test kernel parameter changes temporarily before making them permanent. These changes take effect immediately but are lost on reboot.
# Increase network receive buffer size
sudo sysctl net.core.rmem_max=134217728
Adjust memory swappiness (lower = less swap usage)
sudo sysctl vm.swappiness=10
Enable IP forwarding for routing
sudo sysctl net.ipv4.ip_forward=1
Verify temporary changes
Confirm your temporary changes are active and test application behavior before making changes permanent.
# Verify the changes took effect
sysctl net.core.rmem_max
sysctl vm.swappiness
sysctl net.ipv4.ip_forward
Make permanent changes with sysctl.conf
Add permanent kernel parameter changes to the main sysctl configuration file. These settings are applied at boot time.
sudo cp /etc/sysctl.conf /etc/sysctl.conf.backup
# Network optimizations
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.rmem_default = 65536
net.core.wmem_default = 65536
Memory management
vm.swappiness = 10
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
Security settings
kernel.dmesg_restrict = 1
net.ipv4.conf.default.rp_filter = 1
Create modular configurations in sysctl.d
Use the /etc/sysctl.d/ directory to organize settings by purpose. Files are processed in lexicographical order.
sudo mkdir -p /etc/sysctl.d
# High-performance network settings
net.core.netdev_max_backlog = 5000
net.core.somaxconn = 1024
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_congestion_control = bbr
# Security hardening
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
Apply permanent changes
Load the new configuration without rebooting to test your permanent settings.
# Reload all sysctl settings
sudo sysctl -p
Reload specific configuration file
sudo sysctl -p /etc/sysctl.d/99-network-tuning.conf
Reload all files in sysctl.d
sudo sysctl --system
Common kernel parameters for optimization
Web server optimization
These parameters improve performance for high-traffic web servers and applications handling many concurrent connections.
# Increase connection queue size
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 5000
TCP buffer optimization
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
Connection handling
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_fin_timeout = 10
Database server optimization
Parameters optimized for database workloads with large memory requirements and specific I/O patterns.
# Memory management for databases
vm.swappiness = 1
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
vm.overcommit_memory = 2
vm.overcommit_ratio = 80
Shared memory settings
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
kernel.shmmni = 4096
Semaphore settings
kernel.sem = 250 32000 100 128
Security hardening parameters
Essential security settings to protect against common network attacks and information disclosure.
# Kernel security
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.yama.ptrace_scope = 1
Network security
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
IP spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
Ignore ping requests
net.ipv4.icmp_echo_ignore_all = 1
Verify your setup
# Verify sysctl is working
sysctl --version
Check that settings are loaded
sysctl -a | grep -E "(net.core.somaxconn|vm.swappiness|kernel.dmesg_restrict)"
Verify configuration files are valid
sudo sysctl -p /etc/sysctl.conf
sudo sysctl --system
Test specific parameters
sysctl net.core.rmem_max
sysctl vm.dirty_ratio
Troubleshoot sysctl permission errors
Handle read-only parameters
Some kernel parameters are read-only and cannot be modified. These typically reflect hardware capabilities or kernel build options.
# Check if parameter is writable
ls -la /proc/sys/net/core/rmem_max
Read-only parameters show this error
sysctl: setting key "kernel.osrelease": Read-only file system
Fix permission denied errors
Most sysctl modifications require root privileges. Always use sudo when making changes.
# Wrong - will fail with permission denied
sysctl net.core.rmem_max=134217728
Correct - use sudo
sudo sysctl net.core.rmem_max=134217728
Validate configuration syntax
Test configuration files for syntax errors before applying them system-wide.
# Test configuration file syntax
sudo sysctl -p /etc/sysctl.d/99-network-tuning.conf
Check for typos in parameter names
sudo sysctl net.core.nonexistent 2>&1 | grep "No such file"
Best practices and safety guidelines
- Start with temporary changes: Use
sysctl -w parameter=valueto test before making permanent changes - Document your changes: Add comments to configuration files explaining why each parameter was modified
- Monitor system behavior: Check application performance and system logs after making changes
- Use modular configuration: Organize settings in
/etc/sysctl.d/by purpose for easier management - Keep backups: Always backup
/etc/sysctl.confbefore making changes - Understand the parameters: Read kernel documentation before modifying critical settings
When optimizing for specific applications, consider how they interact with other system components. For example, increasing network buffers may require adjusting application-specific settings like process limits and resource monitoring.
For containerized environments, kernel parameters affect all containers on the host. Consider using memory cgroups for container-specific resource control instead of global kernel tuning.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Permission denied when setting parameter | Missing sudo privileges | Use sudo sysctl parameter=value |
| Read-only file system error | Parameter is read-only | Check ls -la /proc/sys/path for write permissions |
| No such file or directory | Parameter name typo or not available | Use sysctl -a | grep keyword to find correct name |
| Settings lost after reboot | Not saved to configuration file | Add to /etc/sysctl.conf or /etc/sysctl.d/ |
| Invalid argument error | Value outside acceptable range | Check kernel documentation for valid ranges |
| System becomes unstable | Inappropriate parameter values | Reboot to restore defaults, then adjust gradually |
Next steps
- Monitor system performance with sar and sysstat to measure the impact of your optimizations
- Advanced Linux performance tuning for comprehensive optimization strategies
- Optimize memory management and swap for memory-intensive applications
- Combine sysctl tuning with NGINX optimization for web server performance
- Database-specific kernel tuning for PostgreSQL and other database systems
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Script configuration
SCRIPT_NAME="$(basename "$0")"
BACKUP_DIR="/etc/sysctl.backup.$(date +%Y%m%d_%H%M%S)"
# Usage message
usage() {
echo "Usage: $SCRIPT_NAME [OPTIONS]"
echo "Configure Linux kernel parameters with sysctl for system optimization"
echo ""
echo "OPTIONS:"
echo " --network-only Apply only network optimizations"
echo " --security-only Apply only security hardening"
echo " --memory-only Apply only memory management settings"
echo " --custom FILE Apply settings from custom file"
echo " --rollback Rollback to previous configuration"
echo " --help Show this help message"
exit 1
}
# Logging functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Cleanup function
cleanup() {
if [ $? -ne 0 ]; then
log_error "Script failed. Keeping backup at $BACKUP_DIR for manual recovery."
log_error "To rollback: sudo cp $BACKUP_DIR/sysctl.conf /etc/sysctl.conf && sudo sysctl -p"
fi
}
trap cleanup EXIT
# Check if running as root or with sudo
check_privileges() {
if [ "$EUID" -ne 0 ]; then
log_error "This script must be run as root or with sudo"
exit 1
fi
}
# Auto-detect distribution
detect_distro() {
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
SYSCTL_PKG="procps"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
SYSCTL_PKG="procps-ng"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
SYSCTL_PKG="procps-ng"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
else
log_error "Cannot detect distribution. /etc/os-release not found."
exit 1
fi
}
# Install required packages
install_packages() {
echo "[1/7] Installing required packages..."
if [ "$PKG_MGR" = "apt" ]; then
apt update > /dev/null 2>&1
fi
if ! command -v sysctl >/dev/null 2>&1; then
log_info "Installing $SYSCTL_PKG package"
$PKG_INSTALL $SYSCTL_PKG > /dev/null 2>&1
else
log_info "sysctl already installed"
fi
}
# Create backup
create_backup() {
echo "[2/7] Creating backup of current configuration..."
mkdir -p "$BACKUP_DIR"
chmod 755 "$BACKUP_DIR"
if [ -f /etc/sysctl.conf ]; then
cp /etc/sysctl.conf "$BACKUP_DIR/"
fi
if [ -d /etc/sysctl.d ]; then
cp -r /etc/sysctl.d "$BACKUP_DIR/"
fi
log_info "Backup created at $BACKUP_DIR"
}
# Apply network optimizations
apply_network_settings() {
log_info "Applying network optimizations"
cat > /etc/sysctl.d/99-network-optimization.conf << 'EOF'
# Network buffer sizes
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.rmem_default = 65536
net.core.wmem_default = 65536
# Network performance
net.core.netdev_max_backlog = 5000
net.core.somaxconn = 1024
# TCP settings
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 120
net.ipv4.tcp_max_syn_backlog = 8192
# Enable BBR congestion control if available
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
EOF
chmod 644 /etc/sysctl.d/99-network-optimization.conf
}
# Apply security settings
apply_security_settings() {
log_info "Applying security hardening"
cat > /etc/sysctl.d/99-security-hardening.conf << 'EOF'
# Kernel security
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
kernel.kexec_load_disabled = 1
kernel.yama.ptrace_scope = 2
# Network security
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
# ICMP security
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
# SYN flood protection
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5
EOF
chmod 644 /etc/sysctl.d/99-security-hardening.conf
}
# Apply memory management settings
apply_memory_settings() {
log_info "Applying memory management optimizations"
cat > /etc/sysctl.d/99-memory-optimization.conf << 'EOF'
# Memory management
vm.swappiness = 10
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
vm.vfs_cache_pressure = 50
vm.min_free_kbytes = 65536
# Shared memory
kernel.shmmax = 268435456
kernel.shmall = 4194304
# File handles
fs.file-max = 2097152
EOF
chmod 644 /etc/sysctl.d/99-memory-optimization.conf
}
# Apply custom settings from file
apply_custom_settings() {
local custom_file="$1"
if [ ! -f "$custom_file" ]; then
log_error "Custom file not found: $custom_file"
exit 1
fi
log_info "Applying custom settings from $custom_file"
cp "$custom_file" /etc/sysctl.d/99-custom-settings.conf
chmod 644 /etc/sysctl.d/99-custom-settings.conf
}
# Configure main sysctl settings
configure_sysctl() {
echo "[3/7] Configuring sysctl parameters..."
# Create sysctl.d directory if it doesn't exist
mkdir -p /etc/sysctl.d
chmod 755 /etc/sysctl.d
case "$MODE" in
"network")
apply_network_settings
;;
"security")
apply_security_settings
;;
"memory")
apply_memory_settings
;;
"custom")
apply_custom_settings "$CUSTOM_FILE"
;;
*)
apply_network_settings
apply_security_settings
apply_memory_settings
;;
esac
}
# Apply settings
apply_settings() {
echo "[4/7] Applying new sysctl settings..."
# Test configuration first
if ! sysctl -p /etc/sysctl.d/*.conf >/dev/null 2>&1; then
log_error "Configuration test failed. Rolling back..."
rollback_settings
exit 1
fi
# Apply all settings
sysctl --system > /dev/null 2>&1
log_info "Settings applied successfully"
}
# Rollback function
rollback_settings() {
echo "[5/7] Rolling back to previous configuration..."
if [ -d "$BACKUP_DIR" ]; then
if [ -f "$BACKUP_DIR/sysctl.conf" ]; then
cp "$BACKUP_DIR/sysctl.conf" /etc/sysctl.conf
fi
if [ -d "$BACKUP_DIR/sysctl.d" ]; then
rm -rf /etc/sysctl.d/*
cp -r "$BACKUP_DIR/sysctl.d/"* /etc/sysctl.d/ 2>/dev/null || true
fi
sysctl --system > /dev/null 2>&1
log_info "Rollback completed"
else
log_error "No backup found for rollback"
exit 1
fi
}
# Verify configuration
verify_settings() {
echo "[6/7] Verifying configuration..."
local failed=0
# Test a few key parameters
if [ "$MODE" != "custom" ]; then
# Check if we can read some values
sysctl kernel.dmesg_restrict >/dev/null 2>&1 || ((failed++))
sysctl vm.swappiness >/dev/null 2>&1 || ((failed++))
sysctl net.core.rmem_max >/dev/null 2>&1 || ((failed++))
fi
if [ $failed -eq 0 ]; then
log_info "Configuration verification passed"
else
log_warn "Some parameters may not be available on this kernel"
fi
}
# Display summary
display_summary() {
echo "[7/7] Configuration completed successfully!"
echo ""
echo "Summary:"
echo "- Backup created at: $BACKUP_DIR"
echo "- Configuration files in: /etc/sysctl.d/"
echo "- Settings applied and active"
echo ""
echo "To view current parameters:"
echo " sysctl -a | grep <parameter>"
echo ""
echo "To rollback if needed:"
echo " sudo $SCRIPT_NAME --rollback"
}
# Main execution
main() {
# Parse arguments
MODE="all"
CUSTOM_FILE=""
ROLLBACK=false
while [[ $# -gt 0 ]]; do
case $1 in
--network-only)
MODE="network"
shift
;;
--security-only)
MODE="security"
shift
;;
--memory-only)
MODE="memory"
shift
;;
--custom)
MODE="custom"
CUSTOM_FILE="$2"
shift 2
;;
--rollback)
ROLLBACK=true
shift
;;
--help)
usage
;;
*)
log_error "Unknown option: $1"
usage
;;
esac
done
# Validate custom file argument
if [ "$MODE" = "custom" ] && [ -z "$CUSTOM_FILE" ]; then
log_error "Custom file path required with --custom option"
usage
fi
check_privileges
detect_distro
if [ "$ROLLBACK" = true ]; then
# Find latest backup
BACKUP_DIR=$(ls -td /etc/sysctl.backup.* 2>/dev/null | head -1)
if [ -z "$BACKUP_DIR" ]; then
log_error "No backup found for rollback"
exit 1
fi
rollback_settings
log_info "Rollback completed successfully"
exit 0
fi
install_packages
create_backup
configure_sysctl
apply_settings
verify_settings
display_summary
}
# Handle help request
if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
usage
fi
main "$@"
Review the script before running. Execute with: bash install.sh