Introduction
Linux performance tuning represents one of the most valuable skills for system administrators, DevOps engineers, and backend developers. Whether you’re managing high-traffic web servers, databases, or containerized applications, understanding how to optimize kernel parameters can dramatically improve throughput, reduce latency, and maximize resource utilization. In 2026, with workloads becoming increasingly demanding and cloud costs mounting, proper system tuning is more relevant than ever.
This comprehensive guide explores Linux performance tuning across multiple dimensions: memory management, CPU scheduling, I/O subsystems, network stack optimization, and filesystem performance. You’ll learn not just which parameters to adjust, butๆด้่ฆ็ๆฏ understanding why these changes matter and how to measure their impact. We’ll cover both traditional sysctl tuning and modern approaches using tools like tuned and systemd resources management.
Understanding the Linux Performance Landscape
Before diving into specific tuning parameters, it’s essential to understand how the Linux kernel manages resources and where bottlenecks typically occur. Modern Linux systems consist of multiple subsystems that interact in complex ways, and optimizing one area may impact others.
The Performance Pyramid
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LINUX PERFORMANCE LAYERS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโ โ
โ โApplicationโ โ
โ โ Layer โ โ
โ โโโโโโฌโโโโโโ โ
โ โ โ
โ โโโโโโผโโโโโโ โ
โ โ System โ โ
โ โ Calls โ โ
โ โโโโโโฌโโโโโโ โ
โ โ โ
โ โโโโโโผโโโโโโ โ
โ โ Kernel โ โ
โ โ Subsystemsโ โ
โ โโโโโโฌโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโ โ
โ โผ โผ โผ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ Memory โ โ CPU โ โ Network โ โ
โ โ Manager โ โScheduler โ โ Stack โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Identifying Bottlenecks
Effective tuning requires first identifying where performance constraints exist. Common bottleneck categories include:
- CPU-bound: Applications requiring intensive computation
- Memory-bound: Systems running into RAM limits or swap thrashing
- I/O-bound: Disk-intensive workloads limited by storage speed
- Network-bound: Applications limited by network throughput or latency
# Quick system overview
uptime
# Load average: 0.52, 0.58, 0.59 - check against CPU count
# Memory usage
free -h
# total used free shared buff/cache available
# Mem: 31Gi 4.2Gi 24Gi 345Mi 2.6Gi 26Gi
# Swap: 2.0Gi 0B 2.0Gi
# CPU info
lscpu | grep -E "^CPU\(s\)|^Model name|^Thread|^Core"
# CPU(s): 16
# Thread(s) per core: 2
# Core(s) per socket: 8
# Model name: Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz
# I/O statistics
iostat -x 1 5
# %util shows disk utilization
# await shows average wait time in milliseconds
# Network statistics
netstat -s | head -30
# Or better:
ss -s
sysctl Configuration
The sysctl interface allows runtime modification of kernel parameters without rebooting. Parameters are organized hierarchically under /proc/sys/, with corresponding configuration files in /etc/sysctl.conf and /etc/sysctl.d/.
Basic sysctl Operations
# View all current parameters
sysctl -a
# View specific parameter
sysctl net.ipv4.tcp_rmem
# net.ipv4.tcp_rmem = 4096 131072 6291456
# Set parameter temporarily (lost on reboot)
sysctl -w net.ipv4.tcp_fastopen=3
# Make persistent across reboots
echo "net.ipv4.tcp_fastopen=3" >> /etc/sysctl.conf
# Or create custom file
cat > /etc/sysctl.d/99-custom.conf << 'EOF'
# Custom performance tuning
net.ipv4.tcp_fastopen = 3
EOF
# Reload configuration
sysctl --system
# Load from specific file
sysctl -p /etc/sysctl.d/99-custom.conf
Important sysctl Categories
The kernel parameters are organized by subsystem:
# Common parameter categories
# vm.* - Virtual memory management
# net.* - Network stack
# net.core.* - Core network parameters
# net.ipv4.* - IPv4 specific
# net.ipv6.* - IPv6 specific
# fs.* - Filesystem parameters
# kernel.* - General kernel parameters
# vm.zone_reclaim_mode - Zone reclaim mode
Memory Tuning
Memory management is fundamental to system performance. The Linux kernel employs sophisticated algorithms for allocating, caching, and reclaiming memory. Proper tuning can significantly improve performance for memory-intensive workloads.
Virtual Memory Parameters
# /etc/sysctl.d/99-memory.conf
# ====== VM Parameters ======
# Minimum free memory before processes can be killed
# Higher values = more aggressive memory reserves
vm.min_free_kbytes = 65536
# Memory overcommit behavior
# 0 - heuristic, 1 - always overcommit, 2 - never overcommit
vm.overcommit_memory = 0
vm.overcommit_ratio = 50
# Swappiness - lower = less likely to swap
# 0-10 for databases, 60 for desktop
vm.swappiness = 10
# VFS cache pressure - lower = keep more dentry/inode cache
vm.vfs_cache_pressure = 50
# Memory reclaim behavior
vm.zone_reclaim_mode = 0
# Transparent hugepage settings (database workloads)
# madvise - only use when explicitly requested
# always - always use (can cause latency spikes)
# never - disable
vm.nr_hugepages = 128
Huge Pages for Database Workloads
Large databases benefit significantly from huge pages, which reduce Translation Lookaside Buffer (TLB) misses:
# Check current huge page usage
grep -i huge /proc/meminfo
# AnonHugePages: 0 kB
# ShmemHugePages: 0 kB
# HugePages_Total: 128
# HugePages_Free: 128
# HugePages_Rsvd: 0
# HugePages_Surp: 0
# Hugepagesize: 2048 kB
# Set huge pages (for PostgreSQL, MySQL, Oracle)
# Add to /etc/sysctl.d/99-hugepages.conf
vm.nr_hugepages = 256
# For applications to use huge pages
# PostgreSQL: shared_buffers = 4GB (use huge pages)
# MySQL: large_pages = 1 in my.cnf
Network Memory Buffers
Network performance heavily depends on socket buffer sizes:
# /etc/sysctl.d/50-network.conf
# ====== Network Memory ======
# TCP memory auto-tuning
# Format: min, default, max
net.ipv4.tcp_rmem = 4096 131072 6291456
net.ipv4.tcp_wmem = 4096 16384 6291456
# Set socket buffer max
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
# Enable TCP memory accounting
net.ipv4.tcp_mem = 786432 1048576 26777216
# TCP advanced options
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_no_metrics_save = 1
Network Performance Tuning
The Linux network stack is highly configurable. For high-throughput workloads, proper tuning is essential.
TCP Optimization
# /etc/sysctl.d/60-tcp.conf
# ====== TCP Tuning ======
# Connection tracking
net.netfilter.nf_conntrack_max = 1048576
net.nf_conntrack_max = 1048576
# Connection tracking table size
net.netfilter.nf_conntrack_tcp_timeout_established = 7200
# TCP connection limits
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_max_syn_backlog = 8192
# TCP keepalive
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 5
# TCP performance
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_slow_start_after_idle = 0
# TCP congestion control (bbr, cubic, reno)
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
# TIME_WAIT reuse
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
Network Interface Tuning
# Ring buffer size (increases with ethtool)
# Check current settings
ethtool -g eth0
# Ring parameters for eth0:
# Pre-set maximums:
# RX: 4096
# RX Mini: 4096
# TX: 4096
# Current hardware settings:
# RX: 256
# RX Mini: 256
# TX: 256
# Increase ring buffer
ethtool -G eth0 rx 4096 tx 4096
# Enable interrupt coalescing
ethtool -C eth0 rx-usecs 100 tx-usecs 100
# Offload features
ethtool -K eth0 gro on gso on tso on
# Queue count (for multiqueue NICs)
ethtool -L eth0 combined 4
High-Performance Network Server
For extreme performance scenarios:
# /etc/sysctl.d/70-highperf.conf
# Disable IPv6 if not needed
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
# Increase file limits
fs.file-max = 2097152
# Network core tuning
net.core.netdev_max_backlog = 50000
net.core.optmem_max = 25165824
# TCP buffer sizes for high bandwidth
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# Disable reverse path filtering
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
# Accept source routing
net.ipv4.conf.all.accept_source_route = 1
net.ipv6.conf.all.accept_source_route = 1
CPU and Scheduler Tuning
The Linux scheduler has evolved significantly, with the Completely Fair Scheduler (CFS) handling most workloads efficiently. However, specific scenarios benefit from tuning.
Process Scheduling
# /etc/sysctl.d/40-scheduler.conf
# Scheduler tuning
kernel.sched_child_runs_first = 0
# Autogroup (process grouping for desktop responsiveness)
kernel.sched_autogroup_enabled = 1
# CPU frequency governor (set via cpufreq-set)
# performance - max frequency always
# powersave - min frequency always
# ondemand - dynamic based on load
# conservative - gradual frequency changes
# For low-latency applications
kernel.sched_latency_ns = 10000000
kernel.sched_min_granularity_ns = 1000000
kernel.sched_wakeup_granularity_ns = 2000000
CPU Isolation and Affinity
For real-time or latency-sensitive workloads:
# Isolating CPUs (add to kernel command line in GRUB)
# isolcpus=1,2,3
# Set CPU affinity for processes
# Pin nginx to CPUs 1-3
taskset -c 1-3 nginx
# Or programmatically in C
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(1, &mask);
CPU_SET(2, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
I/O Subsystem Tuning
Storage I/O performance depends on both hardware and kernel parameters. Modern SSDs and NVMe devices require different tuning than spinning disks.
I/O Scheduler
# Check current scheduler
cat /sys/block/sda/queue/scheduler
# [mq-deadline] kyber bfq none
# Set scheduler (for SSDs, use none or mq-deadline)
echo none > /sys/block/sda/queue/scheduler
# For NVMe devices
echo none > /sys/block/nvme0n1/queue/scheduler
# For spinning disks, bfq or mq-deadline
echo mq-deadline > /sys/block/sda/queue/scheduler
echo bfq > /sys/block/sda/queue/scheduler
I/O Scheduler Parameters
# Make scheduler changes persistent
# /etc/udev/rules.d/60-scheduler.rules
ACTION=="add|change", SUBSYSTEM=="block", KERNEL=="sd[a-z]", ATTR{queue/scheduler}="none"
ACTION=="add|change", SUBSYSTEM=="block", KERNEL=="nvme[0-9]n1", ATTR{queue/scheduler}="none"
# I/O queue depth
# For SSDs/NVMe, increase queue depth
echo 256 > /sys/block/sda/queue/nr_requests
echo 1024 > /sys/block/nvme0n1/queue/nr_requests
# Read-ahead (for spinning disks)
blockdev --getra /dev/sda
# Default: 256 (128KB)
blockdev --setra 4096 /dev/sda # 2MB read-ahead
# Add deadline parameters
echo 0 > /sys/block/sda/queue/iosched/fifo_batch
echo 1 > /sys/block/sda/queue/iosched/read_expire
echo 300 > /sys/block/sda/queue/iosched/write_expire
Filesystem Options
Different filesystems have different optimal mount options:
# /etc/fstab examples
# ext4 for data
/dev/sdb1 /data ext4 defaults,noatime,nodiratime,commit=60 0 2
# xfs for large files
/dev/sdb1 /data xfs defaults,noatime,nodiratime,attr2,logbufs=8,logdev=/dev/sda3 0 0
# btrfs for snapshots
/dev/sdb1 /data btrfs defaults,noatime,space_cache=v2,compress=zstd 0 0
# tmpfs for temporary files
tmpfs /tmp tmpfs defaults,noatime,mode=1777,size=4G 0 0
# Common options:
# noatime - Don't update inode access times
# nodiratime - Don't update directory inode access times
# nobarrier - Disable write barriers (safe with BBU)
# discard - Enable TRIM for SSDs
# commit=60 - Commit every 60 seconds (reduce writes)
File Descriptor Limits
File descriptors are critical for any server handling many connections or open files:
# Temporary change (process level)
ulimit -n 65535
# System-wide (add to /etc/security/limits.conf)
* soft nofile 1048576
* hard nofile 1048576
root soft nofile 1048576
root hard nofile 1048576
# Kernel limit
echo 1048576 > /proc/sys/fs/file-max
echo 1048576 > /proc/sys/fs/nr_open
# For containers, also set
# /etc/sysctl.d/90-container.conf
fs.file-max = 1048576
Kernel Tuning Tools
Beyond manual sysctl configuration, several tools automate tuning:
tuned and ktune
# Install
yum install tuned
# Check status
systemctl status tuned
tuned-adm active
# List available profiles
tuned-adm list
# Available profiles:
# - balanced
# - desktop
# - latency-performance
# - network-throughput
# - powersave
# - throughput-performance
# - virtual-guest
# - virtual-host
# Select profile
tuned-adm profile network-throughput
# Custom profile
mkdir -p /etc/tuned/myprofile
cat > /etc/tuned/myprofile/tuned.conf << 'EOF'
[main]
include=throughput-performance
[sysctl]
net.core.netdev_max_backlog = 50000
net.ipv4.tcp_rmem = 4096 131072 16777216
EOF
tuned-adm profile myprofile
cpupower
# Install
yum install kernel-tools
# View current settings
cpupower frequency-info
# Set governor
cpupower frequency-set -g performance
# Or for all cores
cpupower -c all frequency-set -g performance
Monitoring and Validation
After applying changes, validate their impact:
Performance Testing
# Network performance
iperf3 -s # Server
iperf3 -c server -P 10 # Client with parallelism
# Disk performance
fio --name=randwrite --ioengine=libaio --direct=1 --bs=4k --numjobs=1 --size=1G --rw=randwrite --runtime=60
# Memory bandwidth
stream
# CPU performance
sysbench cpu --cpu-max-prime=20000 run
# System-level benchmarks
sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
sysbench fileio --file-total-size=2G --file-test-mode=rndrw run
sysbench fileio --file-total-size=2G cleanup
Continuous Monitoring
# Use sar for historical analysis
# Install: yum install sysstat
sar -n DEV 1 5 # Network interface statistics
sar -B 1 5 # Paging statistics
sar -W 1 5 # Swap statistics
sar -q 1 5 # Load averages
sar -r 1 5 # Memory utilization
# Use vmstat
vmstat 1 5
# Use iostat
iostat -x 1 5
Production Safety
When applying tuning in production, follow these guidelines:
# 1. Test in staging first
# 2. Apply changes gradually
# 3. Measure before and after
# 4. Document all changes
# 5. Have rollback plan
# Backup original config
cp -r /etc/sysctl.d /etc/sysctl.d.backup
# Rollback
sysctl -p /etc/sysctl.d.backup/00-system.conf
# Monitor for issues
journalctl -xe -u systemd-sysctl # Check for errors
dmesg | tail # Kernel messages
Example Complete Configuration
Here’s a comprehensive sysctl configuration for a high-performance web server:
# /etc/sysctl.d/99-webserver.conf
# ====== Network ======
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_rmem = 4096 131072 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 50000
net.core.optmem_max = 25165824
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 5
net.netfilter.nf_conntrack_max = 1048576
net.nf_conntrack_max = 1048576
# ====== Memory ======
vm.min_free_kbytes = 65536
vm.overcommit_memory = 1
vm.swappiness = 10
vm.vfs_cache_pressure = 50
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
# ====== File Handles ======
fs.file-max = 2097152
# ====== Kernel ======
kernel.pid_max = 65536
kernel.threads-max = 65536
# ====== Apply ======
sysctl --system
Conclusion
Linux performance tuning is both an art and a science. The sheer number of tunable parameters can be overwhelming, but understanding the fundamentals of how each subsystem works allows you to make informed decisions. Always measure before and after changes, document your modifications, and maintain rollback capabilities.
The key principles remain consistent: identify bottlenecks first, tune incrementally, and validate changes with reproducible benchmarks. Modern Linux distributions ship with reasonable defaults, but for high-throughput applications, the tuning recommendations in this guide can significantly improve performance. Remember that the optimal configuration depends on your specific workloadโwhat works for a database server may not suit a web server, and vice versa.
Start with the baseline recommendations, monitor your system’s behavior under load, and refine as needed. With careful attention to kernel parameters, you can extract substantial performance gains from your Linux infrastructure.
Comments