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_INTERVAL
are 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 Bluetoothdebugfs
entries. 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_latency
set to the target value (default0
): This tells the peripheral device (your mouse) how many connection events it can skip.0
means it should not skip any, aiming for the most immediate communication, which is crucial for minimizing perceived lag.conn_min_interval
set 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_interval
set 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:
logger
commands 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 2
sudo vi /usr/local/bin/set_bluetooth_latency.sh # Paste the script content here, then save and exit.
Make it executable:
1
sudo chmod +x /usr/local/bin/set_bluetooth_latency.sh
Create a new
udev
rule file, e.g.,/etc/udev/rules.d/99-bluetooth-low-latency.rules
:1
ACTION=="add", SUBSYSTEM=="bluetooth", KERNEL=="hci[0-9]*", RUN+="/usr/local/bin/set_bluetooth_latency.sh"
Reload the
udev
rules and trigger them:1
sudo 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
debugfs
Default 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 thedebugfs
files for your Bluetooth adapter (e.g.,hci0
). Open a terminal and usecat
:1 2 3
cat /sys/kernel/debug/bluetooth/hci0/conn_latency cat /sys/kernel/debug/bluetooth/hci0/conn_min_interval cat /sys/kernel/debug/bluetooth/hci0/conn_max_interval
Replace
hci0
with 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_INTERVAL
variables 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
:1
sudo btmon
Connect your Bluetooth mouse. Look for “Connection Update Complete” events or similar messages (sometimes
LE Connection Update Complete
). These events should show theInterval
andSlave 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=y
for the/sys/kernel/debug/bluetooth
path and its files to be available. Most modern distribution kernels have this enabled. - Permissions: Writing to
debugfs
typically requires root privileges, which is why the script would be run viasudo
or 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.