Skip to content

Linux Performance Tuning — CPU, Memory, Disk & Network Optimization Guide

DodaTech Updated 2026-06-24 8 min read

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.

Should I use tuned or manual sysctl?

Start with tuned for a baseline profile, then override individual parameters in a custom profile if the defaults are insufficient.

How often should I review performance tuning?

After every major workload change or kernel update. Tuning that worked for one application version may hurt the next.

Does kernel tuning affect containerized applications?

Yes — containers share the host kernel. Tuning parameters like vm.swappiness and net.ipv4.tcp_congestion_control affect all containers on the host.

Can performance tuning break my system?

Rarely, but extreme values can cause instability. Always test tuning on a staging environment first. Back up sysctl.conf before changes.

What is the single highest-impact tuning parameter?

For most workloads: switching from cubic to bbr congestion control and setting the I/O scheduler to match the storage hardware.

What's Next

Linux System Rescue & Recovery Guide
Kernel Tuning — Advanced Parameters
Monitoring & Logging

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