Linux Performance Tuning — CPU, Memory, Disk & Network Optimization Guide
In this tutorial, you'll learn about Linux Performance Tuning. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Linux performance tuning optimizes kernel parameters, I/O schedulers, CPU governors, and network settings to match workload characteristics — extracting maximum throughput from existing hardware without upgrading.
What You'll Learn
How to tune CPU frequency governors and Process scheduling, configure virtual memory parameters for database workloads, select disk I/O schedulers, optimize network sysctl settings, profile bottlenecks with perf, and make tuning permanent across reboots.
Why Performance Tuning Matters
Default kernel settings prioritize compatibility over performance. A generic Linux install wastes 10–30% potential throughput on the same hardware. Correctly tuned systems serve more requests, use less CPU, and reduce latency. DodaZIP's compression cluster runs with tuned CPU governors, nohz_full isolation, and dedicated I/O threads — processing 40% more data per watt than default settings.
Learning Path
flowchart LR A[Swap Management] --> B[Performance Tuning
You are here] B --> C[System Rescue] B --> D[Kernel Tuning] style B fill:#f90,color:#fff
CPU Tuning
Governor Selection
# List available governors
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
# Check current governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# Set to performance (all cores)
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# For battery-sensitive systems, use ondemand or schedutil
| Governor | Use Case |
|---|---|
| performance | Maximum frequency always — servers, latency-sensitive apps |
| powersave | Minimum frequency — low-power, background tasks |
| ondemand | Ramp up on load — desktops, variable workloads |
| schedutil | Kernel-driven scaling — modern default, good balance |
Process Scheduling
# Set scheduler policy for a process
sudo chrt -f 10 -p 12345 # SCHED_FIFO with priority 10
sudo chrt -r 20 -p 12345 # SCHED_RR with priority 20
sudo chrt -b 0 -p 12345 # SCHED_BATCH (background)
# Check scheduler
chrt -p 12345
# Set nice value (lower = higher priority)
sudo renice -5 -p 12345
# CPU affinity — pin process to specific cores
sudo taskset -pc 0,1 12345
sudo taskset -pc 2-3 12345
Isolating CPU Cores
Dedicate cores to specific workloads by removing them from the general scheduler:
# Add to kernel cmdline
isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3
# Then use taskset to pin processes to isolated cores
sudo taskset -pc 2-3 $(pgrep myapp)
Memory Tuning
VM Parameters for Database Workloads
# Reduce dirty page ratios for databases (PostgreSQL, MySQL)
sudo sysctl vm.dirty_ratio=10 # Max % of memory that can be dirty
sudo sysctl vm.dirty_background_ratio=3 # Start writeback at 3%
# Increase max memory map count for Elasticsearch/MongoDB
sudo sysctl vm.max_map_count=262144
# Reduce overcommit for safety
sudo sysctl vm.overcommit_memory=2 # No overcommit
sudo sysctl vm.overcommit_ratio=80 # Allow 80% of RAM+swap
# Huge pages for database workloads
echo 512 | sudo tee /proc/sys/vm/nr_hugepages
Transparent Huge Pages (THP)
THP helps some workloads and hurts others (especially databases):
# Check current state
cat /sys/kernel/mm/transparent_hugepage/enabled
# Disable for database servers
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
# Or use madvise mode (only on madvise() call)
echo madvise | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
Disk I/O Tuning
I/O Scheduler Selection
# Check current scheduler
cat /sys/block/sda/queue/scheduler
# Set scheduler (for NVMe: none; for SSD: mq-deadline; for HDD: bfq)
echo mq-deadline | sudo tee /sys/block/sda/queue/scheduler
echo none | sudo tee /sys/block/nvme0n1/queue/scheduler
| Scheduler | Best For | Behavior |
|---|---|---|
| none (NVMe) | NVMe SSDs | No reordering — hardware handles it |
| mq-deadline | SATA SSDs | Fair per-Process I/O with latency limits |
| bfq | HDDs, desktops | Per-Process fairness, prevents starvation |
| kyber | Fast SSDs | Low latency, simple algorithm |
Block Device Tuning
# Increase read-ahead (helps sequential workloads)
sudo blockdev --setra 4096 /dev/sda # 4096 sectors = 2MB
# Queue depth (NR requests)
echo 256 | sudo tee /sys/block/sda/queue/nr_requests
# Add random I/O tuning for SSDs
echo 0 | sudo tee /sys/block/sda/queue/add_random # No entropy on SSD
echo 1 | sudo tee /sys/block/sda/queue/rq_affinity # CPU affinity for completions
Disk Benchmarking
# Sequential write test
sudo fio --name=seqwrite --ioengine=libaio --direct=1 --bs=1M \
--size=10G --rw=write --numjobs=1 --runtime=30
# Random 4K read test
sudo fio --name=randread --ioengine=libaio --direct=1 --bs=4k \
--size=10G --rw=randread --numjobs=4 --runtime=30
# Mixed read/write (70/30)
sudo fio --name=mixed --ioengine=libaio --direct=1 --bs=4k \
--size=10G --rw=rw --rwmixread=70 --numjobs=4 --runtime=30
Expected output:
seqwrite: (groupid=0, jobs=1): err= 0: pid=12345
write: IOPS=4500, BW=4500MiB/s (4719MB/s)(10.0GiB/2275msec)
Network Tuning
TCP Stack Optimization
# Increase TCP buffer sizes (for high-BDP networks)
sudo sysctl net.core.rmem_max=134217728 # 128MB
sudo sysctl net.core.wmem_max=134217728 # 128MB
sudo sysctl net.ipv4.tcp_rmem='4096 87380 134217728'
sudo sysctl net.ipv4.tcp_wmem='4096 65536 134217728'
# Enable TCP BBR congestion control
sudo sysctl net.ipv4.tcp_congestion_control=bbr
sudo sysctl net.core.default_qdisc=fq
# Increase backlog
sudo sysctl net.core.netdev_max_backlog=5000
sudo sysctl net.core.somaxconn=65535
# Enable TCP fast open
sudo sysctl net.ipv4.tcp_fastopen=3
# Reduce TIME_WAIT sockets
sudo sysctl net.ipv4.tcp_fin_timeout=15
# Increase port range
sudo sysctl net.ipv4.ip_local_port_range='1024 65535'
Ring Buffer and NIC Tuning
# Check and increase NIC ring buffer
sudo ethtool -g eth0
sudo ethtool -G eth0 rx 4096 tx 4096
# Check and enable hardware offloading
sudo ethtool -k eth0 | grep on
# Set coalescing (reduce interrupts)
sudo ethtool -C eth0 rx-usecs 100 tx-usecs 100
Profiling with perf
# Record CPU samples for 30 seconds
sudo perf record -a -g -- sleep 30
# Generate report
sudo perf report
# Generate flamegraph (requires FlameGraph tools)
sudo perf script | ./stackcollapse-perf.pl > out.perf-folded
./flamegraph.pl out.perf-folded > flamegraph.svg
# Record specific process
sudo perf record -p $(pgrep myapp) -g -- sleep 30
# Count hardware events
sudo perf stat -e cycles,instructions,cache-misses,faults -- sleep 10
Expected perf stat output:
Performance counter stats for 'sleep 10':
1,234,567 cycles
567,890 instructions
# 0.46 insn per cycle
12,345 cache-misses
56 faults
10.001234 seconds time elapsed
Tuned — Automated Profile Management
Tuned applies pre-configured tuning profiles for different workloads:
# Install
sudo apt install tuned
# Start and enable
sudo systemctl enable --now tuned
# List available profiles
tuned-adm list
# Apply a profile
sudo tuned-adm profile latency-performance
# For databases
sudo tuned-adm profile throughput-performance
# Custom profile
sudo mkdir /etc/tuned/myprofile/
sudo tee /etc/tuned/myprofile/tuned.conf << 'EOF'
[sysctl]
vm.swappiness = 1
vm.dirty_ratio = 10
vm.dirty_background_ratio = 3
net.ipv4.tcp_congestion_control = bbr
EOF
sudo tuned-adm profile myprofile
# Check active profile
tuned-adm active
Common Errors
1. Performance Governor Overheating Laptops
Setting performance governor on a laptop causes overheating. Use schedutil or ondemand instead, which scale frequency based on actual load.
2. Dirty Page Ratios Too High
Default vm.dirty_ratio=20 means up to 20% of RAM can be dirty. On a 256GB server, that is 51GB — a burst of writes could block I/O for minutes. Lower to 10 for servers.
3. TCP Buffer Auto-tuning Conflicts
Manually setting both tcp_rmem minimum and rmem_max with extreme values can conflict with auto-tuning. Start with conservative values and monitor with ss -i.
4. Disabling THP for All Workloads
THP helps many workloads (batch processing, VMs). Disable only when profiling shows THP causes latency spikes. Use madvise mode for a balanced approach.
5. Over-aggressive CPU Isolation
Isolating cores with isolcpus removes them from the scheduler entirely. If you isolate too many cores, there are not enough for kernel tasks and interrupts. Leave 1–2 cores for system processes.
6. Ethtool Settings Reset After Reboot
ethtool changes are ephemeral. Use a network manager dispatcher script or systemd service to apply settings at boot:
sudo tee /etc/systemd/system/ethtool-tune@.service << 'EOF'
[Unit]
Description=Apply ethtool tuning to %I
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/ethtool -G %I rx 4096 tx 4096
ExecStart=/usr/sbin/ethtool -C %I rx-usecs 100 tx-usecs 100
[Install]
WantedBy=multi-user.target
EOF
7. Not Verifying with Before/After Benchmarks
Every tuning change needs a baseline. Run benchmarks before and after. Without data, you might make things worse. Use fio for disk, iperf3 for network, and sysbench for CPU/memory.
Practice Questions
1. What CPU governor should a production database server use?
performance — maximum frequency always, no ramp-up latency.
2. How do you pin a Process to specific CPU cores?
sudo taskset -pc 2,3 <PID> or sudo taskset -c 2-3 command.
3. What I/O scheduler is recommended for NVMe drives?
none — NVMe drives have internal scheduling that outperforms kernel-level I/O scheduling.
4. Which sysctl parameter reduces the risk of OOM kills on a busy server?
vm.overcommit_memory=2 disables memory overcommit. With vm.overcommit_ratio=80, the kernel rejects allocations that would exceed 80% of RAM+swap.
5. What does sudo tuned-adm profile latency-performance do?
It applies a set of sysctl, disk, and CPU settings optimized for low latency — including performance governor, deadline scheduler, and TCP tuned for low delay.
Challenge: Profile a production server with perf record -a -g -- sleep 60 and generate a flamegraph. Identify the top 3 CPU consumers. Then apply tuned-adm profile throughput-performance, tune dirty ratios, and switch to BBR congestion control. Re-run the profile and measure the difference in instructions per cycle and CPU utilization.
What's Next
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