Linux Performance Tuning with sysctl

A practical guide to tuning kernel parameters for network performance, memory management, and system stability.

← Back to all articles

The Linux kernel is remarkably self-tuning, but default settings are optimized for general-purpose workloads. In production environments—particularly those handling high network throughput, large numbers of concurrent connections, or specific application patterns—adjusting kernel parameters can yield significant performance improvements.

The sysctl command is the primary tool for viewing and modifying kernel parameters at runtime[reference:8]. This guide covers the parameters I adjust most frequently in enterprise Linux environments.

1. Understanding sysctl

The sysctl command allows you to view and change kernel parameters to alter the behavior of the operating system, including network settings, security features, and resource limits[reference:9].

To view all current settings:

sysctl -a

To view a specific parameter:

sysctl net.core.rmem_max

To set a parameter temporarily (until reboot):

sysctl -w net.core.rmem_max=16777216

To make changes persistent across reboots, add them to /etc/sysctl.conf or a file in /etc/sysctl.d/[reference:10]:

echo "net.core.rmem_max = 16777216" >> /etc/sysctl.conf
sysctl -p

2. Network Performance Tuning

Network performance is often the first area where tuning is needed, particularly for servers handling large file transfers, streaming, or high-frequency API traffic.

2.1. Socket Buffer Sizes

Socket buffers determine how much data can be queued for sending or receiving before the application needs to process it. For high-bandwidth, high-latency networks (often called "long fat pipes"), increasing buffer sizes is essential[reference:11].

Recommended settings for a 10G NIC with up to 100ms RTT:

# /etc/sysctl.conf
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

The tcp_rmem and tcp_wmem parameters specify minimum, default, and maximum buffer sizes for TCP sockets[reference:12].

Caution: Setting buffer sizes too large wastes memory. Each socket can be set to the size the application requests, and the kernel doubles this value[reference:13]. Monitor memory usage after making these changes.

2.2. TCP Congestion Control

The default TCP congestion control algorithm (typically CUBIC) works well for most environments. For high-bandwidth scenarios, BBR (Bottleneck Bandwidth and RTT) can provide significant throughput improvements[reference:14].

To check the current algorithm:

sysctl net.ipv4.tcp_congestion_control

To enable BBR:

# /etc/sysctl.conf
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

The fq (Fair Queue) scheduler is recommended for best BBR performance[reference:15].

2.3. Connection Tracking

For servers handling many concurrent connections (web servers, load balancers), the connection tracking table can become a bottleneck:

net.netfilter.nf_conntrack_max = 1048576

Monitor current connection tracking usage:

cat /proc/sys/net/netfilter/nf_conntrack_count

3. Memory and File System Tuning

3.1. Swappiness

The vm.swappiness parameter controls how aggressively the kernel swaps memory pages. The default is 60, which is often too high for production servers.

vm.swappiness = 10

A value of 10 tells the kernel to prefer reclaiming memory from the page cache rather than swapping, which is usually desirable for application servers.

3.2. File System Cache

For servers with large amounts of RAM, increasing the page cache pressure can improve file system performance:

vm.vfs_cache_pressure = 50

The default is 100. Lower values cause the kernel to retain directory and inode cache longer.

4. Security-Related sysctl Settings

Several sysctl parameters improve system security with minimal performance impact:

# IP spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0

# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

# Protect against SYN flood attacks
net.ipv4.tcp_syncookies = 1

5. A Performance Tuning Workflow

When tuning a new server, I follow this process:

  1. Establish a baseline: Run sysctl -a and save the output.
  2. Identify bottlenecks: Use iperf3, netstat, and ss to understand current performance[reference:16].
  3. Apply targeted changes: Focus on the specific bottleneck (network, memory, or disk).
  4. Test and measure: Re-run performance tests to validate improvements.
  5. Document changes: Add comments to /etc/sysctl.conf explaining each parameter and why it was changed.

This methodical approach ensures that changes are intentional and measurable.

Pro Tip: The systemd-analyze blame command can help identify slow services during boot[reference:17]—a useful starting point for performance investigations that go beyond kernel tuning.

6. Additional Resources

For deeper dives into specific areas: