Fix Your PipeWire Audio on Linux: Low-Latency Recording

PipeWire achieves sub-10ms recording latency on Linux by configuring the quantum (buffer size) to 64 or 128 samples at 48 kHz, combined with setting your user’s real-time scheduling priority through the rtkit service or a dedicated audio group with PAM limits. Most “PipeWire doesn’t work” complaints trace back to misconfigured ALSA UCM profiles, Bluetooth codec fallbacks, or WirePlumber rules that silently override your intended audio routing. What follows covers every layer of the stack - from PipeWire’s architecture down to ALSA period sizes - so you can stop copy-pasting config snippets from forum threads until something accidentally works.
Understanding PipeWire’s Architecture in 2026
PipeWire replaced both PulseAudio and JACK on every major Linux distribution by 2025. Version 1.4.x ships as the default audio (and video) server on Fedora, Ubuntu, Arch, openSUSE, and Debian. Knowing how its components fit together saves you from spending an evening chasing symptoms that a five-minute config check would have caught.
PipeWire itself is the core server. It manages a graph of audio nodes, handles device access, and provides compatibility layers for PulseAudio, JACK, and ALSA clients. It does not decide how nodes connect to each other - that job belongs to the session manager.

WirePlumber (version 0.5.x) is the default session manager. It decides which microphone feeds which application, how Bluetooth devices negotiate codecs, and what happens when you plug in a new pair of headphones. When audio routing behaves unexpectedly, WirePlumber’s rules are almost always the place to look.
The PulseAudio compatibility layer (pipewire-pulse) lets every PulseAudio application work without modification. For JACK applications, pw-jack wraps the JACK API calls and routes them through PipeWire’s graph. In practice, this means you can run Ardour, Firefox, and a Bluetooth speaker simultaneously without conflicts - something that was painful or impossible with the old PulseAudio/JACK split.
Audio processing runs in a real-time thread. The central concept here is the quantum, which is the buffer size measured in samples. The math is straightforward:
| Quantum | Sample Rate | Latency |
|---|---|---|
| 1024 | 48 kHz | 21.3 ms |
| 256 | 48 kHz | 5.3 ms |
| 128 | 48 kHz | 2.7 ms |
| 64 | 48 kHz | 1.3 ms |
Lower quantum means lower latency, but it also means the CPU has less time to process each buffer. If the system cannot keep up, you get xruns (buffer underruns) which manifest as clicks, pops, or dropouts.
Configuration lives in two places: /usr/share/pipewire/ holds the defaults (do not edit these - package updates will overwrite them) and ~/.config/pipewire/ holds your user overrides. Drop-in configuration files go in ~/.config/pipewire/pipewire.conf.d/ and they merge with the defaults.
To see what is actually happening in real time, run pw-top. It shows the current quantum, sample rate, xrun count, and processing load per node. This is the single most useful debugging tool in the PipeWire ecosystem and should be your first stop whenever something sounds wrong.
Configuring Low-Latency for USB Audio Interfaces
USB audio interfaces from Focusrite, MOTU, Behringer, and PreSonus are the most common pro audio devices on Linux. Getting them running at low latency requires specific PipeWire configuration and some system-level tuning.
PipeWire Quantum Settings
Create the file ~/.config/pipewire/pipewire.conf.d/low-latency.conf with these contents:
context.properties = {
default.clock.quantum = 128
default.clock.min-quantum = 64
default.clock.max-quantum = 1024
default.clock.rate = 48000
default.clock.allowed-rates = [ 44100 48000 96000 ]
}This sets a default quantum of 128 samples (2.7 ms at 48 kHz) while allowing the system to dynamically adjust between 64 and 1024 based on load. The allowed-rates list prevents unnecessary resampling when switching between projects at different sample rates.
After saving the file, restart PipeWire:
systemctl --user restart pipewire pipewire-pulse wireplumberVerifying Your Interface
Check that PipeWire sees your USB device:
pw-cli list-objects | grep -i "your-interface-name"For a Focusrite Scarlett 2i2 (4th gen) or similar class-compliant USB device, you can inspect the full node properties with:
pw-dump | jq '.[] | select(.info.props["node.name"] | strings | test("usb")) | .info.props["node.name"]'Verify the sample rate matches your project. A mismatch forces PipeWire to resample, which adds latency and can introduce subtle artifacts.
Real-Time Scheduling
Real-time scheduling is critical for low-latency audio. Without it, the kernel scheduler can preempt the audio thread, causing glitches even when CPU usage is low.
The simplest approach is to make sure rtkit-daemon is running:
systemctl status rtkit-daemonRealtimeKit lets PipeWire request real-time priority without needing root privileges. It works out of the box on most distributions.
For tighter control, add your user to the audio group and create /etc/security/limits.d/audio.conf:
@audio - rtprio 95
@audio - memlock unlimitedThen add yourself to the group and log out/in:
sudo usermod -aG audio $USERMonitoring and Tuning
With pw-top running in a terminal, start recording in your DAW and watch the xrun counter. If xruns are incrementing, increase the quantum from 64 to 128 or from 128 to 256 until they stop. In practice, USB 2.0 interfaces reliably achieve 128 samples (2.7 ms) while USB 3.0 interfaces can often handle 64 samples (1.3 ms).
For device-specific ALSA tuning, you can create a WirePlumber rule that sets api.alsa.period-size and api.alsa.headroom for your specific interface. Create a Lua script in ~/.config/wireplumber/main.lua.d/ that targets your device by its ALSA card name and sets api.alsa.period-size = 128 and api.alsa.headroom = 64. This gives the ALSA backend explicit instructions instead of relying on auto-detection.
Fixing Bluetooth Audio Codec Issues
Bluetooth audio through PipeWire works well when codec negotiation succeeds, but it breaks in confusing ways when it does not. The symptoms - low quality audio, mono output, random disconnections - rarely point directly at the root cause.
Codec Support
PipeWire supports SBC, AAC, aptX, aptX HD, LDAC, LC3, and LC3plus codecs. The aptX family requires the libfreeaptx package (or pipewire-codec-aptx depending on your distribution). Check which codecs are available:
pactl list cards | grep -A 20 "bluez"Look for the available profiles section - it lists every codec your system can negotiate with the connected device.
The SBC Fallback Problem
The single most common Bluetooth audio complaint is that headphones connect but sound terrible because they fell back to SBC instead of a higher-quality codec like LDAC or aptX HD. This happens when the initial codec negotiation fails, and PipeWire silently falls back to the baseline.
Fix it by explicitly setting the preferred codec. You can do this per-session:
wpctl set-codec <device-id> ldacOr permanently through a WirePlumber Bluetooth rule that sets bluez5.codecs = [ ldac aptx_hd aptx aac sbc ] in order of preference.
To force the highest quality LDAC tier (990 kbps), add bluez5.default.rate = 96000 to the WirePlumber configuration for the device.
The Microphone Problem
When you use a Bluetooth headset’s microphone (HFP/HSP profile), the output locks to mono SBC at 16 kHz. This is a fundamental Bluetooth limitation, not a PipeWire bug. The HFP profile simply does not support high-quality stereo output and microphone input simultaneously.
The practical solution is to use a separate USB microphone for calls and voice recording while keeping A2DP stereo output on your Bluetooth headphones. PipeWire handles this split routing without trouble.
PipeWire 1.4 improved mSBC (wideband speech) support for HFP, bumping microphone quality from 8 kHz to 16 kHz narrowband. Make sure your system has BlueZ 5.76 or newer and up-to-date Bluetooth adapter firmware to take advantage of this.
Random Disconnections
If Bluetooth devices disconnect randomly, power management and WiFi coexistence are the usual suspects. Reset the Bluetooth adapter:
sudo btmgmt power off && sudo btmgmt power onOn laptops with combo WiFi/Bluetooth chips (especially Intel), WiFi and Bluetooth can interfere with each other. Disabling Bluetooth coexistence for the iwlwifi driver sometimes helps:
echo "options iwlwifi bt_coex_active=0" | sudo tee /etc/modprobe.d/iwlwifi-bt.confReboot after making this change.
JACK Compatibility and DAW Setup
Professional audio applications like Ardour , REAPER , Bitwig Studio , and Carla expect a JACK server. PipeWire’s JACK compatibility layer works well in 2026, but it has specific setup requirements.
Using pw-jack
The pw-jack wrapper sets LD_PRELOAD to redirect JACK API calls to PipeWire:
pw-jack ardour8For system-wide JACK compatibility, symlink libjack.so to PipeWire’s implementation. Most distribution packages handle this automatically when you install pipewire-jack.
Ardour 8.x and REAPER 7.x both detect PipeWire’s JACK interface natively. Bitwig Studio 5.x has native PipeWire support and does not need the JACK wrapper at all.
Transport and Sync
JACK transport (play/stop/locate synchronization) works through PipeWire. Multiple JACK applications can share transport control, and PipeWire handles sample-accurate sync correctly. If you run Ardour and Hydrogen simultaneously, hitting play in one starts both - just as it would with a standalone JACK server.
Plugins
LV2 and CLAP plugins work natively. VST3 plugins through yabridge work with PipeWire, though some heavy plugins may require bumping the quantum up to 256 or 512 if their processing adds latency that cannot fit within a smaller buffer.

Carla is both a plugin host and a visual patchbay. It renders the PipeWire audio graph as if it were JACK, so you can visually route audio between applications, create processing chains, and insert plugins between sources and sinks.
Troubleshooting JACK Connection Errors
If a JACK application reports “cannot connect to JACK server,” verify PipeWire is actually running:
systemctl --user status pipewire pipewire-pulse wireplumberThen check that the JACK compatibility library is installed. The package name varies by distribution:
- Fedora/RHEL:
pipewire-jack-audio-connection-kit - Ubuntu/Debian:
pipewire-jack - Arch:
pipewire-jack
Diagnosing and Fixing Common PipeWire Problems
This section collects the problems that come up most often on forums and bug trackers, organized by symptom so you can jump straight to your issue.
No Sound After Login
Check the default sink:
wpctl statusIf it shows no default sink, set one manually:
wpctl set-default <sink-id>If the device shows up but is listed as unavailable, WirePlumber may have disabled it after a failed probe. Restart WirePlumber:
systemctl --user restart wireplumberAudio Crackling or Popping
This is almost always a timing problem. Try these fixes in order:
- Reduce sample rate from 96 kHz to 48 kHz
- Increase quantum from 64 to 256
- Check for USB hub contention - plug your audio interface directly into a motherboard USB port
- Check for IRQ conflicts:
cat /proc/interrupts | grep snd
USB audio interfaces sharing a hub with other high-bandwidth devices (webcams, external drives) will crackle under load.
Routing Preferences Lost on Reboot
WirePlumber stores routing decisions in ~/.local/state/wireplumber/. If this directory lives on a tmpfs filesystem or gets cleared during boot, your routing preferences disappear every session. Verify the directory persists:
ls -la ~/.local/state/wireplumber/If it is empty after every reboot, check whether your distribution mounts ~/.local/state as tmpfs or whether a cleanup script is removing the contents.
Volume Stuck at 100% or 0%
Some ALSA UCM (Use Case Manager) profiles have broken mixer controls for specific hardware. Check what ALSA sees:
alsamixer -c 0Switch cards with F6 if your device is not card 0. If the mixer shows no usable controls, the UCM profile for your hardware may be incorrect. Check /usr/share/alsa/ucm2/ for your device’s profile and compare it against the upstream alsa-ucm-conf
repository for fixes.
Simultaneous Output to Multiple Devices
The old PulseAudio trick of using module-combine-sink does not exist in PipeWire. Instead, use pw-loopback to create a virtual link between nodes:
pw-loopback --capture-props='node.target=<source-sink-id>' --playback-props='node.target=<second-sink-id>'Or configure WirePlumber linking rules to automatically route specific streams to multiple outputs.
Screen Sharing Audio Capture
For Discord, OBS, and other applications that need to capture desktop audio:
- OBS 31.x has native PipeWire capture built in
- For Discord in the browser, enable WebRTC PipeWire capture through
xdg-desktop-portal-wlr(for wlroots compositors) orxdg-desktop-portal-gnome(for GNOME) - The PipeWire screen capture portal handles both video and audio streams, so applications that use the portal API get audio capture for free
PipeWire in 2026 is stable and capable enough for professional audio work on Linux. Set your quantum based on actual xrun testing rather than picking an arbitrary number, make sure real-time scheduling is configured through rtkit or PAM limits, and always check WirePlumber’s rules when routing behaves unexpectedly. Run pw-top as your primary diagnostic tool, and keep your configuration in ~/.config/pipewire/pipewire.conf.d/ where package updates will not touch it.
Botmonster Tech