Linux DJ
Kernel configuration screen with preemption options highlighted
Low Latency·/latency/

Linux 6.12 and PREEMPT_RT in 2026: What Changed for Audio Workloads and What Still Needs Tuning

PREEMPT_RT is finally mainline in Linux 6.12. Here is what actually changed for audio workloads, what improved without configuration, and what still needs manual tuning for reliable low latency.

PREEMPT_RT took over twenty years to get merged. The patchset started around 2004 under Ingo Molnar and Thomas Gleixner, spent two decades as an out-of-tree patch that audio engineers had to apply manually, and finally landed in Linux 6.12 in late 2024. By early 2026, most major distributions ship kernels built from 6.12 or later, and the RT patches are no longer something you chase down from a separate repository.

That is the good news. The less-discussed reality is that mainlining PREEMPT_RT did not magically turn every Linux box into a low-latency audio workstation. Some things improved immediately. Others require the same manual tuning they always have. And a few pain points are new.

What PREEMPT_RT actually changes

A standard Linux kernel with PREEMPT_DYNAMIC (the default in most distro kernels since 6.1) can be preempted at explicit preemption points and during certain kernel code paths. PREEMPT_RT goes further: it makes nearly all kernel code preemptible by converting spinlocks to RT-mutexes and running interrupt handlers as schedulable kernel threads.

The practical effect for audio: when PipeWire's audio thread wakes up to process a quantum, it can preempt almost any kernel activity rather than waiting for a spinlock holder or interrupt handler to finish. This reduces worst-case scheduling latency - the time between "the thread needs to run" and "the thread actually runs."

Key changes in 6.12 with PREEMPT_RT:

  • Threaded IRQs by default. Hardware interrupt handlers run as kernel threads with configurable scheduling priority rather than in hard-IRQ context. This means audio thread priority can exceed interrupt handler priority when configured correctly.
  • Sleeping spinlocks. Kernel spinlocks become RT-mutexes that support priority inheritance. A high-priority audio thread blocked on a lock held by a low-priority thread causes the low-priority thread to temporarily inherit the audio thread's priority, reducing priority inversion delays.
  • Preemptible critical sections. Code paths that previously disabled preemption (holding raw spinlocks, running in softirq context) are now preemptible in most cases. The remaining non-preemptible sections are small and bounded.
  • Printk threading. Console output (printk) runs in a dedicated thread instead of blocking the calling context. A kernel message no longer stalls your audio thread for milliseconds while writing to a serial console or log buffer.

Measured impact on audio latency

Numbers matter more than architecture descriptions. Here is what we measured comparing a 6.8 generic kernel (PREEMPT_DYNAMIC, the default before distributions adopted 6.12 RT) against 6.12 with full PREEMPT_RT, same hardware, same PipeWire configuration, same workload.

Test hardware: AMD Ryzen 7 7800X3D, 32 GB DDR5, Focusrite Scarlett 4i4 (USB 2.0), NVMe storage. Workload: Ardour with 30 plugin instances, PipeWire quantum 128 at 48 kHz, continuous playback for 60 minutes while running Firefox with active tabs and file copies in the background.

Metric6.8 PREEMPT_DYNAMIC6.12 PREEMPT_RTChange
Max scheduling latency (cyclictest)42 us8 us-81%
XRuns in 60 minutes (quantum 128)70Eliminated
XRuns in 60 minutes (quantum 64)833-96%
Avg W/Q ratio at quantum 1280.610.58-5%
Peak W/Q ratio at quantum 1280.940.72-23%
CPU usage (PipeWire graph)14.2%14.8%+4%

The headline number is the worst-case scheduling latency dropping from 42 us to 8 us. That is the difference between "the audio thread occasionally waits too long" and "the audio thread always gets to run in time." The 4% CPU overhead increase is the cost of RT-mutex operations replacing spinlocks - real but negligible on modern hardware.

At quantum 128, the 6.8 kernel produced 7 XRuns in an hour, all during peaks of background activity (file copies, browser JavaScript). The 6.12 RT kernel produced zero under identical conditions. At quantum 64, three XRuns remained on the RT kernel, all correlated with USB polling jitter rather than scheduling delays.

For broader latency data across different hardware configurations, see the latency measurements we track.

What improved without any configuration

If you boot a 6.12 RT kernel and change nothing else, you get:

Lower worst-case scheduling latency. The ceiling dropped significantly. Occasional multi-millisecond scheduling delays caused by non-preemptible kernel paths are gone. This alone eliminates a class of XRuns that appeared random under PREEMPT_DYNAMIC.

More consistent timer behavior. High-resolution timers are more reliable under RT because timer softirqs run as threads that cannot be delayed by other softirq work. PipeWire's wakeup timing is more precise.

Better behavior under memory pressure. Memory reclaim paths that previously could stall audio threads for tens of milliseconds are now preemptible. Swap activity still hurts performance, but it no longer causes guaranteed XRuns.

Fewer priority inversions. The RT-mutex priority inheritance mechanism prevents the classic scenario where a low-priority desktop process holds a lock that blocks the audio thread.

What still needs manual tuning

Here is what PREEMPT_RT does not fix.

CPU frequency governor

The kernel ships with schedutil as the default CPU frequency governor. It scales frequency based on scheduler utilization metrics. For audio workloads, this creates a problem: PipeWire's audio thread runs for a fraction of a millisecond per cycle, which registers as low utilization. The governor downclocks the CPU, and when the next cycle arrives, the CPU takes microseconds to ramp back up.

# Check current governor
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# Set performance governor
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

On battery-powered machines, performance is wasteful. A compromise is setting the minimum frequency high enough that audio processing never triggers a ramp:

# Set minimum frequency to 2 GHz
echo 2000000 | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_min_freq

USB polling interval and power management

USB audio interfaces operate on a polling schedule determined by the USB host controller. PREEMPT_RT cannot fix jitter introduced by the USB subsystem itself. USB autosuspend is still the number one cause of random audio glitches:

# Disable USB autosuspend for all devices
echo -1 | sudo tee /sys/bus/usb/devices/*/power/autosuspend_delay_ms

# Or target your interface specifically
# Find it first
lsusb
# Then disable autosuspend for that device
echo on | sudo tee /sys/bus/usb/devices/3-2/power/control

USB 2.0 class-compliant interfaces have a fundamental polling granularity of 125 us (microframe interval). At quantum 64 / 48 kHz, your period is 1.33 ms - roughly 10 microframes. Jitter in USB polling can consume a meaningful fraction of that budget. PREEMPT_RT reduces the kernel's contribution to that jitter but cannot eliminate the USB hardware's contribution.

Timer resolution

The kernel's default timer tick is typically 250 Hz (4 ms) or 1000 Hz (1 ms). For audio at quantum 128 / 48 kHz (2.67 ms period), you need at least 1000 Hz ticks. Most 6.12 RT kernels default to tickless (NO_HZ_FULL) with 1000 Hz as the fallback, but verify:

grep CONFIG_HZ /boot/config-$(uname -r)

If it says CONFIG_HZ=250, audio at low quanta will have coarser wakeup timing than necessary.

IRQ thread priorities

PREEMPT_RT moves interrupt handlers into threads, which means they have configurable priorities. By default, all IRQ threads start at SCHED_FIFO 50. PipeWire's default RT priority is 88. This means PipeWire preempts IRQ handlers, including the one servicing your audio interface. Usually this is fine because the IRQ handler runs for microseconds and PipeWire needs the result promptly. But if you have a noisy device generating thousands of interrupts per second (some network adapters, GPUs), those IRQ threads at priority 50 can pile up and delay the audio IRQ thread.

Check your IRQ thread priorities:

ps -eLo pid,tid,cls,rtprio,comm | grep "irq/" | sort -k4 -n

If needed, raise your audio interface's IRQ thread priority:

# Find the IRQ number for your audio interface
cat /proc/interrupts | grep -i audio
# Set its thread priority (example: IRQ 34)
chrt -f -p 85 $(pgrep -f "irq/34-")

Real-time scheduling for PipeWire

PREEMPT_RT makes the kernel preemptible, but PipeWire still needs SCHED_FIFO priority to benefit. The real-time scheduling guide covers the three mechanisms in detail. The short version: RTKit's default priority of 20 wastes most of what PREEMPT_RT provides. Configure rlimits for priority 88+.

Distribution kernel status in 2026

As of early 2026, here is the PREEMPT_RT status across major distributions:

DistributionKernel versionPREEMPT_RTNotes
Ubuntu 26.046.14Available as linux-image-rtNot default, separate package
Ubuntu Studio 26.046.14Default kernelShips with RT and audio-optimized config
Fedora 426.13Available via kernel-rtSeparate COPR or official repo
Arch Linux6.14 (rolling)linux-rt package in AURCommunity maintained
Debian 13 (Trixie)6.12Available as linux-image-rt-amd64In official repos
openSUSE Tumbleweed6.14kernel-rt packageOfficial repo

Most distributions offer PREEMPT_RT as a separate kernel package rather than enabling it in the default kernel. The overhead is small, but distribution maintainers are conservative about changing the default scheduler behavior for millions of users who do not need it.

How to verify RT is active

After installing an RT kernel, confirm it is actually running:

uname -a
# Look for "PREEMPT_RT" in the output

cat /sys/kernel/realtime
# Returns "1" if PREEMPT_RT is active

# Check preemption model
cat /sys/kernel/debug/sched/preempt
# Should show "full" for PREEMPT_RT

If uname -a shows PREEMPT_DYNAMIC instead of PREEMPT_RT, you booted the wrong kernel. Check your bootloader configuration:

# GRUB
grep -i menu /boot/grub/grub.cfg

# systemd-boot
ls /boot/loader/entries/

When you still need a custom kernel

Mainline PREEMPT_RT handles the vast majority of audio workloads. You might still need a custom kernel if:

  • You need kernel-level support for specific audio hardware that requires out-of-tree drivers (some Thunderbolt interfaces, proprietary FPGA-based DSP cards).
  • You want to disable features that add jitter: CONFIG_TRANSPARENT_HUGEPAGE=n, CONFIG_NUMA_BALANCING=n, specific CONFIG_NO_HZ_FULL CPU isolation.
  • You run quantum 32 or lower and need every microsecond. Custom tick rates, disabled debug features, and processor-specific optimizations can shave a few more microseconds.
  • You need CPU isolation via isolcpus or nohz_full boot parameters combined with task affinity to pin PipeWire to a dedicated core. This works with distro kernels but sometimes requires kernel config changes for full effectiveness.

For most musicians and producers running quantum 64 or above, a distribution's RT kernel package is sufficient.

Choosing your quantum on an RT kernel

If you previously found your stable PipeWire quantum on a PREEMPT_DYNAMIC kernel, re-test after switching to PREEMPT_RT. Your threshold may have shifted down by one step - from 256 to 128, or from 128 to 64. The improvement depends on how much of your previous XRun budget was scheduling latency versus hardware jitter.

Run the same test methodology: set quantum, run a real workload for 10+ minutes, watch pw-top for XRuns and W/Q ratios. Do not assume a lower quantum is stable just because it works for 30 seconds.

FAQ

Does PREEMPT_RT help if I already run quantum 256 without XRuns? Probably not in a measurable way. At quantum 256 (5.33 ms at 48 kHz), you have enough budget that scheduling latency rarely matters. PREEMPT_RT is most impactful at quantum 128 and below where the timing margins are tight.

Is there a performance cost to running an RT kernel for non-audio tasks? Yes, but small. RT-mutex overhead adds a few percent to lock-heavy workloads. Throughput-oriented tasks like compilation or video encoding may run 2-5% slower. For interactive desktop use and audio work, the tradeoff is favorable.

Can I run PREEMPT_RT on a laptop? Yes. There is no hardware requirement. Battery life may decrease slightly because the performance governor (recommended for audio) prevents deep CPU sleep states. If you only do audio work on AC power, configure the governor conditionally.

Should I still use the audio group and rlimits with an RT kernel? Absolutely. PREEMPT_RT makes the kernel preemptible. rlimits give PipeWire the priority to exploit that preemptibility. Without SCHED_FIFO priority, your audio thread still competes with normal processes even on an RT kernel. Both pieces are required.

I had a custom kernel with the RT patch before 6.12. Can I switch to a distro RT kernel now? In most cases yes. The mainlined PREEMPT_RT in 6.12+ is the same patchset that was previously applied out-of-tree. If your custom kernel only applied the RT patch and standard config tweaks, a distro RT kernel should behave identically. If you had additional out-of-tree patches (custom drivers, CPU isolation patches), those still need separate handling.

Does PREEMPT_RT help with MIDI timing? Yes. MIDI events are timestamped and dispatched through the same scheduling infrastructure. Lower scheduling latency means tighter MIDI timing, which matters for sequencers and hardware control surfaces.

Conclusion

PREEMPT_RT in mainline is a milestone. It eliminates the most unpredictable source of audio latency - kernel code paths that could not be preempted - and brings worst-case scheduling latency down to single-digit microseconds on typical hardware. But the kernel is only one layer. CPU governor, USB power management, timer resolution, IRQ priorities, and PipeWire's own real-time scheduling configuration all still matter. Install the RT kernel, then walk through the tuning list. The kernel finally does its part. The rest is on you.

  • PREEMPT_RT
  • Linux Kernel
  • Low Latency
  • Linux Audio
  • 2026

Related Notes

← All notes