Debian Performance Optimization: Practical System Tweaks for Faster, Stable Servers

Last updated January 20, 2026 ~18 min read 13 views
Debian Linux administration performance tuning systemd kernel tunables sysctl I/O scheduler network tuning CPU governor memory management swap zram filesystems ext4 XFS Btrfs journald logrotate monitoring capacity planning
Debian Performance Optimization: Practical System Tweaks for Faster, Stable Servers

Debian is often chosen for servers because it is predictable, conservative, and stable. Those same qualities can make a freshly installed system feel “good enough” but not necessarily optimal for a specific workload. Performance work on Debian is less about chasing magic kernel parameters and more about making a few high-impact, low-risk changes that match what the machine actually does: serving web requests, running databases, compiling code, terminating VPN tunnels, or hosting containers.

This article takes a practical approach to debian performance optimization. The goal is to help you tune a Debian system without guessing. You will start by creating a baseline with the right metrics, then apply targeted tweaks in layers: CPU and scheduling, memory and swap, storage I/O, network stack, and service management via systemd. Along the way, you’ll see how to validate that changes improved latency and throughput rather than just shifting bottlenecks.

The techniques here are intentionally “system-level” (kernel/sysctl, systemd, filesystems, and common admin tooling). Application-level tuning can produce major gains too, but it only makes sense after the host OS is stable, observable, and configured appropriately.

Establish a performance baseline before changing anything

Performance tuning without measurement is how servers become folklore-driven snowflakes. Before applying tweaks, capture a baseline that answers two questions: what resource is constrained (CPU, memory, I/O, network) and what metric matters (latency, throughput, tail latency, job completion time).

Start by noting the workload characteristics and the SLO/SLA you care about. A CI runner cares about compile time and I/O amplification from package caches; a database server cares about I/O latency and memory residency; a VPN gateway cares about packet rate and CPU per packet. You want at least one “business” metric (requests/sec, p95 latency, jobs/hour) and a few host metrics.

On Debian, you can get a lot done with sysstat, procps, and a few purpose-built tools:

sudo apt-get update
sudo apt-get install -y sysstat procps htop iotop iftop linux-cpupower ethtool

Enable sysstat collection so you can compare “before and after” even if you weren’t logged in during a spike:

bash
sudo sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
sudo systemctl enable --now sysstat

Now collect a quick snapshot during typical load:

  • CPU: mpstat -P ALL 1, pidstat -u 1, top -H (thread view)
  • Memory: free -m, vmstat 1, pidstat -r 1
  • Disk: iostat -xz 1, iotop -oPa
  • Network: ss -s, ss -ti, sar -n DEV 1, ethtool -S <iface>

A key skill is interpreting a few core signals:

  • High %iowait with elevated disk await times in iostat suggests storage latency is gating throughput.
  • High context switches (cs in vmstat) plus runnable queue growth suggests scheduling pressure or too many threads.
  • Memory pressure shows as rising si/so in vmstat (swap in/out) and increased major faults.
  • Network buffer pressure and retransmits show up in ss -ti and NIC stats.

Scenario 1: A small PostgreSQL server with intermittent latency spikes

Consider a Debian 12 VM running PostgreSQL for an internal app. Average latency is fine, but p95 spikes during business hours. Baseline metrics show %iowait jumps when spikes occur, iostat shows high await on the virtual disk, and vmstat shows occasional swap-out. This points to a combined issue: the VM is memory-constrained (causing reclaim and swapping) and the storage layer has variable latency.

This scenario will come up again as we tune memory/swap and storage behavior in a way that reduces latency sensitivity.

Validate hardware, virtualization, and firmware assumptions

Before kernel tunables, make sure Debian sees what you think you provisioned. Misconfigured CPU frequency scaling, wrong drivers, and mismatched virtual hardware can erase the benefits of later tuning.

Check CPU model, cores, and virtualization flags:

bash
lscpu
cat /proc/cpuinfo | grep -E 'model name|cpu MHz' | head

Check disks and schedulers:

bash
lsblk -o NAME,MODEL,SIZE,ROTA,TYPE,MOUNTPOINT
cat /sys/block/sda/queue/scheduler

ROTA is important: 1 means rotational (HDD), 0 means non-rotational (SSD/NVMe or virt). Many I/O decisions (scheduler, readahead expectations) depend on this.

If this is a VM, verify the paravirtualized drivers are used (virtio for KVM, VMXNET3 for VMware, etc.). On KVM, lsblk should show vda for virtio disks in many setups; on VMware, use lspci and ethtool -i to confirm NIC driver.

Also confirm timekeeping is stable; time drift can cause confusing performance symptoms in logs and metrics:

bash
timedatectl
chronyc tracking 2>/dev/null || true

Keep the system lean: packages, services, and boot-time overhead

A common source of “slowness” on general-purpose Debian installs is simply doing too much by default: extra daemons, periodic jobs, and logging settings that are fine for desktops but noisy on servers.

Start by listing enabled services:

bash
systemctl list-unit-files --type=service --state=enabled
systemctl --type=service --state=running

Do not indiscriminately disable services. Instead, identify what each does and whether it’s needed on this host role. For example, a minimal server may not need bluetooth.service, cups.service, or Avahi (avahi-daemon) at all. Removing needless daemons reduces CPU wakeups, memory footprint, and the chance that a periodic timer collides with a latency-sensitive workload.

Timers can also be surprisingly impactful:

bash
systemctl list-timers --all

If you find a periodic job competing with your peak window (for example, log rotation compressing huge logs), you can often adjust scheduling rather than disabling it.

systemd resource controls as a safer alternative to disabling services

When a service is required but can be contained, systemd’s cgroup controls provide a clean way to cap resource usage. This is often better than ad-hoc nice usage or hoping the scheduler behaves.

For example, if you have a backup job that should not steal I/O from a database, you can create an override:

bash
sudo systemctl edit my-backup.service

Add:

ini
[Service]
CPUWeight=50
IOWeight=50
Nice=10

CPUWeight and IOWeight participate in proportional sharing inside the cgroup hierarchy. These settings help on multi-tenant hosts (CI runners, shared build boxes, or hosts running multiple services) where you want predictable performance rather than peak throughput at the cost of latency.

CPU performance: frequency scaling, governors, and scheduler behavior

CPU tuning on Debian is usually about avoiding unexpected downclocking, preventing excessive interrupts from pinning a core, and keeping the scheduler from bouncing hot threads across CPUs. The right choices differ between laptops and servers; for servers, stable performance is typically preferred over power savings.

Inspect CPU frequency scaling and set a policy intentionally

Debian uses the kernel’s cpufreq subsystem. Modern Intel/AMD systems often use intel_pstate or amd_pstate; others use the acpi_cpufreq driver. View current policy:

bash
cpupower frequency-info

If the governor is set to powersave and the workload is latency-sensitive (web/API, databases, VPN gateways), you may see higher response times under bursty loads. A common approach is to use performance governor on servers where energy saving is not the top priority:

bash
sudo cpupower frequency-set -g performance

To persist this across reboots on Debian, install and enable cpufrequtils or use a systemd unit that sets the governor at boot. With cpufrequtils:

bash
sudo apt-get install -y cpufrequtils
printf 'GOVERNOR="performance"\n' | sudo tee /etc/default/cpufrequtils
sudo systemctl enable --now cpufrequtils

Be careful on shared virtualized hosts: some hypervisors abstract frequency scaling, and forcing a governor may have little effect.

Consider CPU isolation and affinity only when you have a clear need

Pinning processes to CPUs (taskset, systemd CPUAffinity) is sometimes used to reduce jitter. It is most beneficial when you have a noisy neighbor process, frequent interrupts, or a latency-critical single-threaded component.

As a starting point, prefer observing interrupt distribution before pinning anything:

bash
cat /proc/interrupts | head -n 20

If one core is handling most NIC interrupts (common on some systems), that core can become a bottleneck. Techniques like IRQ affinity and RSS (Receive Side Scaling) can spread load, but they are hardware/driver specific. At minimum, ensure RSS is enabled and multiple queues are active when the NIC supports it:

bash
ethtool -l eth0
ethtool -k eth0 | egrep 'rx-hashing|gro|gso|tso'

Avoid making IRQ affinity changes without understanding your driver and queue setup; a misstep can worsen performance.

Scenario 2: A Debian VPN gateway that hits a packet-per-second ceiling

A Debian host terminating WireGuard and doing NAT for remote users often looks “fine” at low throughput, then suddenly pegs one CPU core and drops packets as you scale concurrent tunnels. Baseline data shows one core at 100% softirq, increasing ss -s drops, and NIC stats reporting missed packets.

In that scenario, CPU governor changes won’t help much. What often matters is distributing packet processing (more RX/TX queues, correct RSS configuration), enabling offloads where safe, and ensuring the network stack buffers match the burst profile. We’ll cover the network side later, but the key lesson is that CPU utilization alone is not the metric—softirq time and drops matter.

Memory management: reclaim behavior, swap policy, and avoiding latency spikes

Linux memory management is a frequent cause of “mystery” latency. Debian defaults are conservative and generally safe, but not always ideal for servers with strict tail-latency requirements.

Two common failure modes are:

  1. Reclaim storms: the kernel spends CPU time reclaiming memory, causing application threads to stall.
  2. Swap-induced tail latency: even small swap activity can introduce multi-second stalls for unlucky requests.

Understand what “available memory” means on Linux

Admins sometimes panic when free shows low “free” memory. Linux uses spare RAM as page cache to improve I/O performance. What matters is MemAvailable, not MemFree.

Use:

bash
free -h
vmstat 1

If MemAvailable stays healthy and si/so (swap in/out) are near zero under load, the system is likely fine.

Tune swappiness and reclaim aggressiveness with sysctl

vm.swappiness controls how aggressively the kernel prefers swapping anonymous memory (application heap/stack) versus dropping page cache. For many servers, a lower value reduces the chance of swapping during normal operation.

Create a dedicated sysctl file (preferred over editing /etc/sysctl.conf directly):

bash
sudo tee /etc/sysctl.d/99-performance.conf > /dev/null <<'EOF'

# Reduce swap tendency on servers with adequate RAM

vm.swappiness = 10

# Reduce pressure to reclaim inode/dentry caches aggressively

vm.vfs_cache_pressure = 50
EOF

sudo sysctl --system

These are deliberately moderate. Setting swappiness=0 can be counterproductive on some kernels and workloads; it can prevent proactive swapping and lead to abrupt memory pressure later.

Manage dirty page writeback to avoid I/O bursts

Write-heavy workloads can suffer when too many dirty pages accumulate and then flush in a burst, causing latency spikes for both the application and unrelated processes.

Two relevant sysctls are vm.dirty_background_ratio and vm.dirty_ratio (or their _bytes equivalents). Ratios are simple but can be risky on large-memory servers because they scale with RAM; bytes are more predictable.

A practical approach is to cap dirty data in bytes on servers where latency matters:

bash
sudo tee /etc/sysctl.d/99-dirty-writeback.conf > /dev/null <<'EOF'

# Start background writeback after ~512MiB is dirty

vm.dirty_background_bytes = 536870912

# Force writeback if ~2GiB is dirty

vm.dirty_bytes = 2147483648

# Writeback interval (centiseconds); 1500 = 15s

vm.dirty_writeback_centisecs = 1500
EOF

sudo sysctl --system

These values are not universal. On a small VM with 4–8 GB RAM, 2 GB dirty cap may be too high; on a database server with 256 GB RAM, it may be too low. The point is to choose explicit limits aligned with your storage latency and workload burstiness.

Swap devices, swapfiles, and when zram makes sense

Debian supports swap partitions and swapfiles. Swapfiles are flexible and usually fine on modern kernels. For servers, the decision is rarely “swap or no swap” and more often “how much swap, and how do we prevent pathological swapping?”

For latency-sensitive services, it’s common to keep a small amount of swap as a safety valve (to avoid OOM kills during brief spikes) while tuning swappiness down.

zram (compressed RAM-backed swap) can help when you have occasional memory spikes and want to avoid disk swap latency. It trades CPU for reduced I/O and can be a strong fit for small VMs, build servers, and some container hosts. It is not always ideal for already CPU-bound workloads.

On Debian, systemd-zram-generator is a common approach; availability varies by release and repository. If you deploy zram, treat it as a controlled change: measure CPU overhead and confirm it reduces disk swap I/O during peak.

Scenario 1 revisited: reducing p95 spikes on the PostgreSQL VM

In the PostgreSQL VM scenario, the baseline indicated occasional swapping plus variable storage latency. After lowering swappiness and ensuring Postgres isn’t competing with noisy periodic jobs, the system stops pushing anonymous pages to swap during normal load. Dirty page limits further reduce flush bursts that were amplifying storage latency. The result is not necessarily higher throughput, but a significant improvement in tail latency—the metric the team actually cares about.

Storage I/O: scheduler selection, readahead, filesystem choices, and mount options

Storage performance tuning pays off quickly because disk latency affects everything: databases, package installs, CI caches, and even login responsiveness during spikes.

On Debian, you can tune storage at multiple layers:

  • Kernel block layer (I/O scheduler, request queue parameters)
  • Filesystem (ext4/XFS/Btrfs) and mount options
  • System behavior (writeback settings discussed earlier)

Choose an I/O scheduler appropriate to the device type

Linux offers different I/O schedulers. On many modern systems:

  • NVMe often defaults to none (i.e., minimal scheduling) or mq-deadline.
  • Virtio and SATA SSD often benefit from mq-deadline.
  • HDDs sometimes benefit from bfq for fairness (especially desktops) but servers may prefer deadline-like behavior.

Check the current scheduler:

bash
cat /sys/block/sda/queue/scheduler

To set a scheduler persistently, you typically use kernel command line parameters or udev rules. For example, to use mq-deadline on sda, you can create a udev rule:

bash
sudo tee /etc/udev/rules.d/60-ioschedulers.rules > /dev/null <<'EOF'
ACTION=="add|change", KERNEL=="sda", ATTR{queue/scheduler}="mq-deadline"
EOF

sudo udevadm control --reload-rules
sudo udevadm trigger --type=devices --action=change

Do this selectively and only after verifying the target scheduler exists in /sys/block/<dev>/queue/scheduler. On NVMe devices, the path will be /sys/block/nvme0n1/queue/scheduler.

Tune readahead for the workload

Readahead controls how much data the kernel reads ahead during sequential reads. Too low can hurt streaming and backups; too high can waste cache and pollute memory on random workloads.

Check current readahead (in 512-byte sectors):

bash
sudo blockdev --getra /dev/sda

Set readahead temporarily:

bash
sudo blockdev --setra 4096 /dev/sda

A value like 4096 sectors is 2 MiB. For database workloads with mostly random I/O, smaller readahead (128–512 KiB range) may be better. For sequential workloads (media processing, backup reads), larger can help. Persisting readahead typically uses udev rules similar to the scheduler approach.

Filesystem and mount options: focus on correctness first

Most Debian servers use ext4 or XFS. ext4 is a safe default and performs well for many workloads. XFS can be excellent for large files and parallel I/O. Btrfs offers snapshots and checksumming but requires more operational familiarity.

Mount options can impact performance, but also safety. Avoid turning off barriers/journaling unless you fully understand the durability implications.

Practical, generally safe options include:

  • noatime: avoids updating access time on reads, reducing write amplification.

Example /etc/fstab line:

fstab
UUID=... /var/lib/postgresql ext4 defaults,noatime 0 2

For database directories, ensure alignment with vendor guidance. PostgreSQL, for instance, benefits from consistent low-latency storage and enough shared buffers; filesystem mount tweaks won’t fix an under-provisioned disk.

Separate write-heavy paths to reduce contention

If you can, separate write-heavy paths (database data, WAL/redo logs, container writable layers, journal logs) onto different virtual disks or storage classes. Even in a VM, separate virtual disks may map to different backing stores or caching policies.

This is not always possible, but when it is, it often produces more predictable latency than any sysctl tweak.

Network performance: buffers, congestion control, and kernel queue behavior

Network tuning is often approached with copy-pasted sysctl snippets. On Debian, you should treat network sysctls as workload-dependent and verify with real traffic.

Network performance problems typically fall into a few categories:

  • The host cannot process packets fast enough (CPU/softirq bound).
  • Buffers are too small for the bandwidth-delay product (BDP), limiting throughput on high-latency links.
  • Queues/buffers are too large, causing bufferbloat and increased latency.

The “right” tuning depends on whether you care about throughput, latency, or both.

Inspect current TCP settings and congestion control

Check available congestion control algorithms and which is active:

bash
sysctl net.ipv4.tcp_congestion_control
sysctl net.ipv4.tcp_available_congestion_control

On modern Debian kernels, BBR may be available but not always enabled by default. Changing congestion control can improve throughput on some paths, but it is not universally better and may interact with your network environment.

If you decide to use BBR, you also need fq queuing discipline:

bash
sudo tee /etc/sysctl.d/99-tcp-bbr.conf > /dev/null <<'EOF'
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF

sudo sysctl --system

Only do this if you understand your traffic mix and have a way to validate improvements (e.g., iperf3 tests across representative links, or application-level latency/throughput metrics).

Right-size socket buffers for your environment

For high-throughput links, especially with non-trivial RTT, default buffer limits can constrain performance. A measured approach is to increase maximums moderately, then validate.

Example:

bash
sudo tee /etc/sysctl.d/99-net-buffers.conf > /dev/null <<'EOF'
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.tcp_rmem = 4096 87380 268435456
net.ipv4.tcp_wmem = 4096 65536 268435456
EOF

sudo sysctl --system

These values raise ceilings; actual buffer sizes still depend on autotuning and application behavior. If you run many concurrent connections, very large buffers can increase memory usage; monitoring is essential.

Reduce connection setup overhead where appropriate

For servers with many short-lived connections (some HTTP patterns, certain proxies), you may benefit from ensuring connection tracking and ephemeral port behavior is sane.

Review ephemeral port range:

bash
sysctl net.ipv4.ip_local_port_range

If you see port exhaustion during load tests or bursts, widening the range can help. Also ensure TIME_WAIT reuse settings are not changed recklessly; many “tuning guides” recommend unsafe toggles. Prefer fixing client behavior (keep-alives) or scaling out.

Scenario 3: A Debian CI runner slowed by artifact uploads and TLS overhead

A CI runner that compiles artifacts and uploads them to an internal registry often shows an interesting pattern: CPU is intermittently high during TLS, then network throughput flattens even though the link is fast. Baseline ss -ti shows small send/receive windows and frequent congestion window resets across a higher-latency path to the registry.

After validating with iperf3 and controlled job runs, increasing socket buffer ceilings and enabling a modern congestion control algorithm improves sustained throughput without increasing job-to-job variance. The more meaningful win comes from combining this with disk tuning (reducing I/O contention in the workspace) and systemd resource controls so background package updates don’t compete with builds.

systemd and journald: reduce overhead while keeping auditability

Logging and service supervision are essential, but they can be tuned to avoid self-inflicted load. Debian’s default journald behavior is usually fine, but on busy servers it can contribute to I/O pressure—especially if logs are extremely verbose or stored on slow disks.

Configure journald retention and rate limiting

Inspect journald disk usage:

bash
journalctl --disk-usage

Set reasonable limits in /etc/systemd/journald.conf (create overrides rather than editing vendor defaults when possible). Example settings:

ini
[Journal]
SystemMaxUse=1G
SystemKeepFree=2G
RateLimitIntervalSec=30s
RateLimitBurst=10000

After changes:

bash
sudo systemctl restart systemd-journald

Be cautious with rate limiting if you rely on logs for incident response; overly aggressive limits can hide useful context. The goal is to prevent uncontrolled growth and avoid log storms saturating I/O.

Prefer structured log rotation for large text logs

For services writing to flat files (e.g., Nginx, custom apps), ensure logrotate is configured to avoid compressing massive logs at the busiest time. Consider using delaycompress and schedule rotation off-peak. This is a classic case where “performance tuning” is simply moving heavy housekeeping away from production traffic.

Kernel and sysctl tuning: apply small, testable changes

sysctl tuning is powerful, but it is also where performance folklore thrives. The safest approach is to change a few parameters that match your observed bottleneck, document why, and measure again.

At this point you’ve already made a few sysctl changes for memory and network. Keep them organized in /etc/sysctl.d/ with descriptive filenames. This makes rollback and auditing straightforward.

File descriptor limits and process limits

High-connection servers often run into file descriptor ceilings long before CPU becomes the bottleneck. Check current limits for your service user and system-wide settings.

For the current shell:

bash
ulimit -n

System-wide limits are commonly managed via /etc/security/limits.conf and systemd’s per-service settings. For a systemd service, the most reliable method is a unit override:

bash
sudo systemctl edit nginx.service

Add:

ini
[Service]
LimitNOFILE=1048576

This avoids confusion where PAM limits apply to interactive sessions but not to services.

Reduce needless kernel logging on production

Kernel log verbosity can add overhead during storms. You can review current kernel printk settings:

bash
cat /proc/sys/kernel/printk

If you have a misbehaving driver spamming logs, fix the underlying issue first. Avoid blindly suppressing kernel messages because they are often your first indicator of real faults.

Process-level tuning: priorities, niceness, and I/O class

Once system-level settings are reasonable, you can fine-tune how critical processes compete. This is especially useful on hosts that run multiple roles (not ideal, but common).

CPU scheduling priority (nice) and real-time scheduling

Use nice to make background tasks yield CPU more readily:

bash
sudo nice -n 10 /usr/local/bin/batch-job

Avoid using real-time scheduling (SCHED_FIFO, chrt) unless you have deep understanding; it can starve the system if misapplied. For most server workloads, cgroup weights and sensible niceness are safer.

I/O priority with ionice

If a task is heavy on disk reads/writes (backups, compression), you can lower its I/O priority:

bash
sudo ionice -c2 -n7 -p <pid>

Or start it with lower priority:

bash
sudo ionice -c2 -n7 tar -czf /backup/archive.tgz /data

This is a practical complement to the dirty page and scheduler tuning: instead of trying to globally optimize everything, you explicitly tell the kernel which tasks matter most.

Capacity planning and regression-proofing: keep your optimizations durable

A tuned Debian server can regress after kernel updates, workload changes, or configuration drift. The best performance optimization is one you can verify repeatedly.

Capture configuration state

Track:

  • /etc/sysctl.d/* files you changed
  • systemd overrides (systemctl cat <service> output)
  • kernel command line (/proc/cmdline)
  • filesystem mount options (findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS)

Consider storing these in a configuration management system (Ansible, Puppet, etc.) even if the host is otherwise “manually” managed.

Automate repeatable benchmarks relevant to your workload

Synthetic benchmarks are useful when they mimic real constraints:

  • Disk: fio for IOPS/latency profiles similar to your database or build workload
  • Network: iperf3 across representative paths
  • CPU: application-specific load tests, or compile benchmarks for CI runners

Install fio and iperf3 when appropriate:

bash
sudo apt-get install -y fio iperf3

A simple fio job for random reads (adjust to your device and risk tolerance):

bash
fio --name=randread --filename=/var/tmp/fio.test --size=2G \
    --rw=randread --bs=4k --iodepth=32 --numjobs=4 --direct=1 \
    --runtime=60 --time_based --group_reporting

Do not run destructive tests on production volumes. Use a dedicated test file on a filesystem with enough free space and ensure it won’t evict critical cache unexpectedly.

Tie performance work to observability

If you already use Prometheus node_exporter, Netdata, Zabbix, or another monitoring stack, align your tuning with dashboards:

  • CPU: softirq time, run queue, context switches
  • Memory: major faults, swap I/O, page reclaim
  • Disk: await/latency, utilization, queue depth
  • Network: retransmits, drops, socket memory

The reason is simple: you want tuning to be a controlled change with evidence, and you want alerts that tell you when you’re sliding back toward the old bottleneck.

Putting it together: a staged approach you can defend in a change review

A common failure in performance work is changing many variables at once and being unable to explain which change helped. A staged approach is slower but repeatable.

Start with housekeeping and service containment because it’s low risk and reduces background noise. Then address CPU frequency policy so bursty workloads don’t stall. After that, tune memory reclaim and dirty writeback to reduce tail latency. Next, improve storage behavior with a scheduler choice and readahead aligned to your I/O profile. Finally, tune the network stack only after you can reproduce network-bound issues with tests and metrics.

If you apply this method to the three scenarios in this article:

  • The PostgreSQL VM improves p95 latency primarily through memory and writeback behavior, plus reduced background interference.
  • The VPN gateway improves stability by focusing on packet processing distribution and network stack behavior rather than generic CPU tweaks.
  • The CI runner improves job time by addressing both network throughput and storage contention, then keeping background services contained.

The overarching pattern is that Debian is already a strong baseline; debian performance optimization is about aligning defaults with reality, making changes that are explainable, and keeping the system observable so improvements persist.