Real-Time Fedora Kernel Guide 2026
With the mainline merge of PREEMPT_RT in Linux 6.12 (late 2024), building a real-time Fedora kernel no longer requires applying out-of-tree patches. The RT preemption model is a config option. You have three choices:
# Pre-built RT kernel from COPR (easiest) . # Build via Fedora's fedpkg RPM infrastructure . # Build vanilla from source (most control)
Method A — Pre-Built RT Kernel from COPR
The @kernel-vanilla/stable COPR ships kernel-rt packages for x8664 and aarch64.
sudo dnf -y copr enable @kernel-vanilla/stableVanilla COPR kernels can't be signed for Secure Boot. Check and disable if needed:
sudo dnf install kernel-rt kernel-rt-core kernel-rt-modules kernel-rt-modules-extramokutil --sb-stateSet RT kernel as default and reboot:
sudo mokutil --disable-validation # then reboot through MOK promptssudo grubby --set-default /boot/vmlinuz-*.rt*Verify:
sudo rebootuname -a # look for PREEMPT_RT==Method B — Fedora RPM Build with RT==
Use this if you need Fedora's own kernel patches with RT enabled, or want custom config.
cat /sys/kernel/realtime # should return 1
cat /sys/kernel/debug/sched/preempt # should show "full"sudo dnf install fedpkg fedora-packager rpmdevtools ncurses-devel pesign grubbyCreate kernel-local in the kernel source directory to override Fedora's defaults:
sudo dnf builddep kernel.spec
fedpkg clone -a kernel
cd kernel
git fetch
git switch f44 # or your release branch# kernel-localAlternatively, run make menuconfig and set:
General Setup → Preemption Model → Fully Preemptible Kernel (Real-Time)
General Setup → Timers subsystem → High Resolution Timer Support
General Setup → Timers subsystem → Full dynticks system (tickless)
Processor type and features → Timer frequency → 1000 HZ
Power management → CPU Frequency scaling → Default governor → performance
CONFIG_PREEMPT_RT=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_NO_HZ_FULL=y
CONFIG_HZ_1000=y
CONFIG_HZ=1000
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
Set a unique build ID in kernel.spec:
%define buildid .rtBuild and install:
fedpkg local
cd x86_64
sudo dnf install --nogpgcheck kernel-core-*.rt.*.rpm kernel-modules-*.rt.*.rpm \
kernel-modules-core-*.rt.*.rpm kernel-*.rt.*.rpm
sudo grubby --set-default /boot/vmlinuz-*.rt.*
sudo rebootMethod C — Vanilla Source Build (Most Control)
For the absolute latest RT fixes or exotic configurations.
sudo dnf install git make gcc bc flex bison openssl-devel elfutils-libelf-devel ncurses-devel
mkdir -p ~/kernel && cd ~/kernel
git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
git checkout v6.12.16
# RT patch is only needed if your version lacks mainline PREEMPT_RT
wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.12/patch-6.12.16-rt9.patch.xz
xz -d patch-6.12.16-rt9.patch.xz
patch -p1 < patch-6.12.16-rt9.patchConfigure with your running kernel as base:
cp /boot/config-$(uname -r) .config
yes '' | make oldconfig
make menuconfig
Critical config options beyond PREEMPTRT:
CONFIG_NO_HZ_FULL=y — adaptive tickless on isolated cores
CONFIG_HZ=1000 — 1ms timer granularity
CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y — prevent downclocking
CONFIG_DEBUG_PREEMPT=n — disable debugging overhead
CONFIG_SLUB_DEBUG=n — lower latency
CONFIG_LOCKDEP=n — huge latency penalty if left on
CONFIG_TRANSPARENT_HUGEPAGE=n — avoid non-deterministic TLB flushes
CONFIG_NUMA_BALANCING=n — prevent NUMA migration jitter
Disable signing keys to avoid build errors:
scripts/config --disable SYSTEM_TRUSTED_KEYSBuild:
scripts/config --disable SYSTEM_REVOCATION_KEYS
scripts/config --set-str CONFIG_SYSTEM_TRUSTED_KEYS ""
scripts/config --set-str CONFIG_SYSTEM_REVOCATION_KEYS ""make -j$(nproc) bindeb-pkg==Why PREEMPTRT Matters for Music==
sudo make modules_install
sudo make install
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot
Measured on a Ryzen 7 7800X3D with a Focusrite Scarlett 4i4 (USB), running Ardour with 30 plugins at quantum 128/48kHz (linuxdj.com):
| Metric | PREEMPTDYNAMIC || PREEMPTRT | |||
|---|---|---|---|---|
| Max scheduling latency (cyclictest) | 42 μs | 8 μs | ||
| XRuns/hour at quantum 128 | 7 | 0 | ||
| XRuns/hour at quantum 64 | 83 | 3 | ||
| Peak W/Q ratio at quantum 128 | 0.94 | 0.72 |
RT eliminates the unpredictable latency tail. Threaded IRQs mean your audio thread can preempt interrupt handlers. Sleeping spinlocks become RT-mutexes with priority inheritance. Critical sections that previously disabled preemption are now preemptible — no more millisecond stalls from filesystem journal commits (kernel.org).
Tips & Tricks Nobody Tells You
1 — USB Autosuspend Is the #1 XRun Culprit
USB audio interfaces get put to sleep by the kernel. This causes intermittent crackles:
echo -1 | sudo tee /sys/bus/usb/devices/*/power/autosuspend_delay_msPersistent udev rule at /etc/udev/rules.d/90-usb-audio-power.rules:
ACTION=="add", SUBSYSTEM=="usb", ATTR{bInterfaceClass}=="01", \
TEST=="power/control", ATTR{power/control}="on"2 — Raise Your Audio Interface's IRQ Thread Priority
PREEMPTRT turns IRQ handlers into threads at SCHED_FIFO 50 by default. PipeWire runs at priority 88. Boost your interface:
cat /proc/interrupts | grep -i audio # find IRQ number (e.g. 34)===3 — Disable Transparent HugePages & NUMA Balancing===
These cause non-deterministic latency spikes. Add to kernel cmdline in /etc/default/grub:
chrt -f -p 85 $(pgrep -f "irq/34-")GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX transparent_hugepage=never numa_balancing=disable"===4 — Isolate CPUs for the Tightest Latency===
Remove cores from the general scheduler:
GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3 irqaffinity=0-1"Pin PipeWire to those cores via config, and disable SMT:
echo off | sudo tee /sys/devices/system/cpu/smt/control===5 — Use rtla timerlat, Not Just cyclictest===
cyclictest shows you how much latency. rtla timerlat (built into the kernel since 6.x) tells you why:
sudo rtla timerlat top -a 150 -Pf:98This captures the blocking thread's stack trace when latency exceeds 150 μs — invaluable for identifying SMIs, drivers, or kernel paths (kernel.org).
===6 — Detect SMIs (System Management Interrupts)===
SMIs are invisible to the kernel and produce 50–300 μs spikes that even PREEMPTRT can't fix:
sudo hwlatdetect --duration=60sIf detected, disable in BIOS — no kernel tuning helps.
7 — PipeWire RT Priority Without RTKit
RTKit defaults to priority 20, wasting what PREEMPTRT provides. Override with a systemd drop-in at ~/.config/systemd/user/pipewire.service.d/realtime.conf:
[Service]===8 — Disable WiFi & Bluetooth During Sessions===
WiFi power management and Bluetooth radios generate thousands of IRQs per second:
LimitRTPRIO=95
LimitMEMLOCK=infinity
LimitNICE=-20iw dev wlan0 set power_save off===9 — Don't Chase the Smallest Buffer===
The stability difference between quantum 64 and 128 is enormous, but the latency difference (1.3 ms vs 2.7 ms at 48 kHz) is imperceptible. Start at 256, work down, stop at the first unstable level and step back one (linuxdj.com).
==Quick Verification Reference==
Check || Command || Good Result
RT kernel || cat /sys/kernel/realtime || 1
Preemption || uname -a || Contains PREEMPT_RT
Governor || cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor || performance
PipeWire RT || ps -eLo cls,rtprio,comm \|| grep pipewire || FF 88
Memory lock || ulimit -l || unlimited
USB autosuspend || cat /sys/bus/usb/devices/*/power/control \|| uniq || on
Isolated CPUs || cat /sys/devices/system/cpu/isolated || Your chosen cores
WiFi power save || iw dev wlan0 get power_save || off
==Sources==
Linux kernel real-time documentation
PREEMPT_RT differences from mainline
Fedora wiki: custom kernel build
Fedora wiki: kernel-vanilla COPR
rtla-timerlat documentation
linuxdj.com: RT latency measurements
linuxdj.com: low-latency audio checklist
realtime-linux.org: getting started with PREEMPT_RT
proteanos.com: RT latency benchmarks
rfkill block bluetooth
Copyright © 2026 Henry Kroll III, thenerdshow.com This web page is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.