How to Fix Audio Delay or Latency Issues on Fedora

Fix Fedora audio delay by reducing PipeWire or PulseAudio buffer sizes in the configuration file and restarting the audio service.

The lag you hear before the sound arrives

You press play on a video and the dialogue arrives half a second after the lips move. You tap a MIDI key and the note trails behind your finger. You are on a recent Fedora release, the system sounds fine otherwise, but the delay is noticeable enough to break immersion. You have already checked your speaker settings and confirmed the correct output device is selected. The problem is not a missing driver. The problem is buffering.

Fedora ships with PipeWire as the default audio server. PipeWire batches audio samples into chunks to keep the CPU from choking on real-time processing. The default chunk size prioritizes stability over speed. When the chunk is too large, you hear the delay. The fix is a configuration override that tells the audio server to use smaller chunks. You do not need to reinstall packages or touch the kernel. You only need to adjust the quantum size and restart the user service.

What is actually happening under the hood

Audio hardware does not process sound one sample at a time. It expects data in fixed-size blocks. The operating system collects samples from applications, packs them into a buffer, and hands the buffer to the sound card. The time it takes for a buffer to travel from the application to the speaker is the latency.

The buffer size is called the quantum. The sample rate is the number of samples per second. Fedora defaults to 48000 Hz. If the quantum is 1024 samples, the latency is 1024 divided by 48000, which equals roughly 21 milliseconds. That sounds small. Human hearing notices delays above 15 milliseconds when watching video or playing instruments. Many desktop environments and media players add their own internal buffers on top of the server buffer. A 21 millisecond server buffer easily becomes 50 to 100 milliseconds of perceived lag.

PipeWire solves the CPU starvation problem by allowing multiple applications to share a single audio stream. It uses a context property system to define defaults. The default.clock.quantum property sets the target chunk size. The default.clock.min-quantum and max-quantum properties set the boundaries. Applications can request a smaller quantum, but the server will clamp it to the minimum. Applications can request a larger quantum, but the server will cap it at the maximum. Lowering the minimum and target forces the server to process smaller chunks more frequently. This reduces delay but increases CPU usage and raises the risk of audio dropouts if the system cannot keep up.

PulseAudio uses the same mathematical model but stores the settings in a plain text configuration file. Fedora transitioned to PipeWire years ago, but the pipewire-pulse compatibility layer still reads some legacy PulseAudio settings. If you are running a custom desktop environment or an older workstation image, you might still be using raw PulseAudio. The tuning approach is identical. You change the buffer size. You restart the daemon. You verify the new latency.

Reboot before you debug. Half the time the symptom is gone after a clean service restart.

How to reduce the buffer size

Fedora stores user configuration overrides in ~/.config/. You never edit files in /usr/lib/ or /etc/ directly. Package updates overwrite system defaults. User overrides survive upgrades and take precedence. PipeWire reads configuration snippets from ~/.config/pipewire/pipewire.conf.d/. Each file in that directory merges into the main context. You only need one file to override the clock properties.

Here is how to create the override directory and write the low-latency configuration.

mkdir -p ~/.config/pipewire/pipewire.conf.d
# Create the directory structure if it does not exist yet
# PipeWire scans this path automatically on startup
# User overrides here safely shadow package defaults

cat > ~/.config/pipewire/pipewire.conf.d/99-low-latency.conf <<EOF
context.properties = {
    default.clock.rate = 48000
    # Force a standard desktop sample rate to avoid resampling overhead
    default.clock.quantum = 128
    # Set the target buffer size to 128 samples
    default.clock.min-quantum = 64
    # Allow applications to request smaller chunks if needed
    default.clock.max-quantum = 512
    # Cap the maximum buffer to prevent runaway latency spikes
}
EOF
# Write the configuration file with explicit quantum boundaries
# The 99- prefix ensures this file loads last and overrides earlier defaults
# JSON-like syntax is parsed by PipeWire's context loader

The 128 target quantum divides by 48000 to yield roughly 2.6 milliseconds of server-side latency. The 64 minimum allows professional audio applications to drop lower when they need it. The 512 maximum prevents media players from accidentally requesting huge buffers that re-introduce the delay.

PipeWire runs as a user service, not a system service. You manage it with systemctl --user. The --user flag tells systemd to operate on your login session's service manager. You do not need sudo for user services. Restarting the service applies the new configuration immediately.

systemctl --user restart pipewire pipewire-pulse wireplumber
# Restart the core audio server and its session manager
# pipewire-pulse handles legacy PulseAudio application compatibility
# wireplumber manages device routing and policy decisions
# The restart is instantaneous and does not drop active connections

If you are maintaining a legacy system that still runs raw PulseAudio, you will edit the daemon configuration instead. The file lives in /etc/pulse/daemon.conf. You must use sudo because it is a system-wide configuration. You only need to uncomment and adjust two lines.

sudo sed -i 's/^;default-fragments = 4/default-fragments = 8/' /etc/pulse/daemon.conf
# Increase the number of fragments to smooth out delivery
# sed modifies the file in place without opening an editor
# The semicolon removal enables the previously commented line

sudo sed -i 's/^;default-fragment-size-msec = 25/default-fragment-size-msec = 25/' /etc/pulse/daemon.conf
# Keep the fragment size at 25 milliseconds
# Smaller fragments combined with more fragments reduce overall buffer depth
# PulseAudio calculates total latency from these two values

pulseaudio -k
# Kill the running PulseAudio daemon
# The daemon auto-restarts immediately with the new configuration
# This is faster than using systemctl for legacy PulseAudio setups

Run journalctl -xe if the service fails to start. The x flag adds explanatory text and the e flag jumps to the end. Most sysadmins type journalctl -xeu pipewire.service muscle-memory style. Read the actual error before guessing.

Verify the new latency

You need to confirm the server is actually using the smaller quantum. PipeWire exposes runtime properties through its command-line tools. The pw-dump utility prints the entire server state. You can filter it to find the active clock properties.

Here is how to query the current quantum and sample rate.

pw-dump | grep -A 5 "clock"
# Dump the PipeWire server state and filter for clock properties
# The output shows the negotiated rate and quantum for the active stream
# grep -A 5 prints the matching line plus five lines of context

The output will show default.clock.quantum alongside the active stream's negotiated values. If you see 128 or 64, the override is active. If you still see 1024 or 2048, the service did not reload correctly or another configuration file is overriding yours. Check the file permissions in ~/.config/pipewire/pipewire.conf.d/. The file must be readable by your user. PipeWire will silently ignore unreadable configuration files.

You can also test the latency with a simple audio loopback. Play a video with distinct dialogue. Tap a table near the microphone and record it. Measure the gap between the tap and the playback. A gap under 10 milliseconds means the tuning is working. A gap over 30 milliseconds means the buffer is still too large or a hardware device is enforcing its own delay.

Trust the package manager. Manual file edits drift, snapshots stay.

Common pitfalls and what the error looks like

Lowering the quantum increases the frequency of context switches. If your CPU is already busy, the audio server will miss deadlines. When the server misses a deadline, it drops samples. You will hear crackling, stuttering, or complete silence. The kernel logs will record an underrun.

pipewire: [  0.000000] spa.alsa: xrun
# The ALSA backend reports a buffer underrun
# xrun means the hardware buffer ran out of data before the next chunk arrived
# This happens when the CPU cannot refill the buffer fast enough

If you see xrun messages in journalctl -t pipewire, increase the quantum back to 256 or 512. Stability matters more than microseconds. You can also check CPU usage with top or htop. If a background process is pegging a core, kill it or move it to a lower priority. Audio scheduling uses real-time priorities by default. Heavy background work will starve the audio thread.

Bluetooth audio interfaces are a different problem. Bluetooth codecs compress audio and introduce fixed hardware buffers. PipeWire cannot override a Bluetooth codec's internal latency. You will see the same xrun messages or persistent delay regardless of your quantum settings. Use a wired connection for low-latency work. USB audio interfaces behave better. They expose their hardware buffer size through ALSA. PipeWire respects the hardware limits but can still tune the software buffer.

SELinux is not the culprit here. Audio buffering is a resource and configuration issue. SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux. Disabling SELinux will not fix audio latency. It will only expose your system to privilege escalation.

Snapshot the system before the upgrade. Future-you will thank you.

When to use low-latency tuning vs alternatives

Use PipeWire quantum tuning when you run modern Fedora and want consistent desktop audio sync without touching the kernel. Use PulseAudio manual overrides when you are maintaining a legacy workstation or running older applications that bypass PipeWire. Use a dedicated real-time kernel when you are running professional DAW software and need sub-5ms latency with guaranteed scheduling. Stay on default buffering when you only watch videos and stream music, because stability matters more than microseconds.

Where to go next