Introduction Link to heading
If you’re experiencing annoying lag or stutter with your Bluetooth mouse or trackpad on Linux, this post might help you fix it.
This approach works by directly adjusting Bluetooth connection parameters through the debugfs interface.
I was seeing serious stutters with my MX Master 3S, especially under heavy load. It became almost unusable. I also had similar problems with an Apple Magic Trackpad 2. The trackpad performs well on Linux and Sway (yes, even gestures), but it was stuttering a lot, which made it impossible to use.
After applying these changes, the situation has improved significantly:
- The trackpad now works perfectly.
- The MX Master 3S still stutters occasionally, but it’s acceptable.
I use the MX Master over Bluetooth instead of its USB receiver because hi-res scrolling is only supported via Bluetooth. I rely on this feature daily. Unfortunately, support for hi-res scrolling through the receiver doesn’t appear to be coming soon: https://gitlab.freedesktop.org/libinput/libinput/-/issues/996
There’s also a relevant reference on the Arch Linux Wiki: https://wiki.archlinux.org/title/Bluetooth_mouse#Mouse_lag
Why the cursor stutters Link to heading
Bluetooth Low Energy (LE) devices, which include most modern mice and trackpads, are designed with power efficiency in mind. To save battery, they negotiate certain connection parameters with your computer (the host) each time they connect. The primary parameters affecting responsiveness are:
| Parameter | Meaning | Desired “Snappy” Value (Script Default) |
|---|---|---|
| min / max interval | How frequently the host and device communicate (1 unit = 1.25 ms) | 6–7 (translates to 7.5-8.75 ms) |
| latency | Number of communication events the device is allowed to skip | 0 |
Many mice will request higher interval values or a non-zero latency to conserve power. Some might also enter low-power “Sniff Modes.” When this happens, your cursor can appear to freeze momentarily or stutter because the device is waiting for its next scheduled slot to communicate with the host. This script aims to force these parameters into a low-latency configuration.
The Solution: A Script to Tweak debugfs
Link to heading
The Linux kernel often exposes detailed Bluetooth adapter settings via its debugfs filesystem. By writing specific values to certain files within this system, we can influence the connection parameters for our Bluetooth devices.
Here is a shell script designed to apply these low-latency settings:
| |
How the Script Works Link to heading
- Configuration Section: At the top,
TARGET_CONN_LATENCY,TARGET_CONN_MIN_INTERVAL, andTARGET_CONN_MAX_INTERVALare defined. These are the values the script will attempt to set. sleep 3: The script waits for 3 seconds. This gives Bluetooth interfaces time to initialize properly, especially if the script is run early during boot or upon device detection.BT_DEBUG_PATH: Defines the standard location for Bluetoothdebugfsentries. It checks if this path exists; if not, it logs an error and exits.- Looping through Adapters: It iterates over all detected Bluetooth Host Controller Interfaces (e.g.,
hci0,hci1). - Parameter Adjustment:
conn_latencyset to the target value (default0): This tells the peripheral device (your mouse) how many connection events it can skip.0means it should not skip any, aiming for the most immediate communication, which is crucial for minimizing perceived lag.conn_min_intervalset to the target value (default6): This sets the minimum desired connection interval (e.g., $6 \times 1.25\text{ms} = 7.5\text{ms}$).conn_max_intervalset to the target value (default7): This sets the maximum desired connection interval (e.g., $7 \times 1.25\text{ms} = 8.75\text{ms}$). By forcing a very short and tight range for the connection interval and disallowing skipped events, the script encourages your mouse and computer to communicate very frequently and without deliberate pauses.
- Logging:
loggercommands send output to the system journal, which helps in verifying the script’s execution and troubleshooting.
Automating with udev Link to heading
To apply these settings automatically every time your Bluetooth adapter is initialized, you can use a udev rule.
Save the script above to a file in a system-wide accessible location. Do NOT use your user’s home directory for scripts run by udev. A good choice is
/usr/local/bin/set_bluetooth_latency.sh.1 2sudo vi /usr/local/bin/set_bluetooth_latency.sh # Paste the script content here, then save and exit.Make it executable:
1sudo chmod +x /usr/local/bin/set_bluetooth_latency.shCreate a new
udevrule file, e.g.,/etc/udev/rules.d/99-bluetooth-low-latency.rules:1ACTION=="add", SUBSYSTEM=="bluetooth", KERNEL=="hci[0-9]*", RUN+="/usr/local/bin/set_bluetooth_latency.sh"Reload the
udevrules and trigger them:1sudo udevadm control --reload-rules && sudo udevadm trigger
This rule will execute your script whenever a Bluetooth hci device is added to the system.
Expected Results & Verification Link to heading
After the script runs (either manually or via udev), re-pair your devices, I hope it will fix the stutters even for you.
There are a few ways to verify the changes:
Directly Check
debugfsDefault Values: This is the most direct way to see if the script has set the adapter’s preferred parameters. After the script has executed, inspect the values written to thedebugfsfiles for your Bluetooth adapter (e.g.,hci0). Open a terminal and usecat:1 2 3cat /sys/kernel/debug/bluetooth/hci0/conn_latency cat /sys/kernel/debug/bluetooth/hci0/conn_min_interval cat /sys/kernel/debug/bluetooth/hci0/conn_max_intervalReplace
hci0with your actual Bluetooth adapter if it’s different (e.g.,hci1). The output values should match theTARGET_CONN_LATENCY,TARGET_CONN_MIN_INTERVAL, andTARGET_CONN_MAX_INTERVALvariables defined at the top of the script.Monitor Live Connection Parameters with
btmon: To see the parameters actually negotiated during an active connection with your mouse, usebtmon:1sudo btmonConnect your Bluetooth mouse. Look for “Connection Update Complete” events or similar messages (sometimes
LE Connection Update Complete). These events should show theIntervalandSlave Latency(orconnLatency). Ideally, these will be at or very close to the values the script aimed for (e.g., Interval around 7.5ms - raw0x0006- or 8.75ms - raw0x0007, and Latency0- raw0x0000).
Important Notes Link to heading
- Kernel Support: Your kernel needs to be compiled with
CONFIG_BT_DBUGFS=yfor the/sys/kernel/debug/bluetoothpath and its files to be available. Most modern distribution kernels have this enabled. - Permissions: Writing to
debugfstypically requires root privileges, which is why the script would be run viasudoor byudev(which runs with root privileges). - Re-pairing: In some cases, you might need to un-pair and then re-pair your Bluetooth mouse for the new connection parameters to take full effect.