How to Enable BBR on Debian 11 (Step-by-Step)

Learn how to enable bbr on debian 11, save settings across reboots, verify the live queue, and fix common Debian VPS kernel errors safely, too.
A glowing orange network path runs beside a server rack and cyan speed gauge on a midnight-blue background.

Enable BBR on Debian 11 to use a modern TCP congestion-control algorithm together with the fq packet scheduler. The change takes about five minutes, applies without opening a firewall port, and can be retained after a reboot.

Prerequisites

  • A Debian 11 (Bullseye) VPS with a kernel newer than 4.9; the standard Debian 11 kernel is from the 5.10 series.
  • SSH access as root, or a normal user with working sudo privileges.
  • Permission to load kernel modules and write files under /etc; a restricted container may not provide either capability.
  • No domain, web server, extra RAM, or extra disk is required because BBR is a kernel-level TCP setting.
  • If you need the server first, choose a Linux VPS from VPSLake and install Debian 11.

BBR changes TCP pacing and capacity estimation; it cannot increase the bandwidth limit of your VPS. Results depend on the route, remote peer, and application.

Step 1: Confirm Debian 11 and inspect TCP

Check the release and running kernel before changing sysctl values so you do not tune a different image or provider-supplied kernel by mistake.

cat /etc/os-release
uname -r
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control

The release output should identify Debian GNU/Linux 11, and a standard Bullseye installation normally reports a 5.10 kernel. The active algorithm is commonly cubic; BBR may already be listed as available.

PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
5.10.0-...-amd64
net.ipv4.tcp_available_congestion_control = reno cubic
net.ipv4.tcp_congestion_control = cubic

Kernel patch numbers and the available algorithm list vary. Do not replace a working provider kernel just to match the sample output.

Step 2: Load BBR for the current boot

On Debian, BBR can be supplied as the tcp_bbr kernel module. Load it before selecting the algorithm so the kernel knows the name when the sysctl is applied.

sudo modprobe tcp_bbr
sysctl net.ipv4.tcp_available_congestion_control

The second command should now include bbr:

net.ipv4.tcp_available_congestion_control = reno cubic bbr

If bbr was already present, modprobe simply confirms that the module can be used. The exact order of the algorithms is not important.

Step 3: Make BBR persistent

Keep the module request and kernel parameters in separate files so the change is easy to audit or remove without touching unrelated Debian settings.

sudo tee /etc/modules-load.d/tcp-bbr.conf >/dev/null <<'EOF'
tcp_bbr
EOF
sudo tee /etc/sysctl.d/99-bbr.conf >/dev/null <<'EOF'
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF
sudo sysctl -p /etc/sysctl.d/99-bbr.conf

The first file asks the boot-time module loader to prepare BBR. The second selects BBR for new TCP connections and sets fair queueing as the default scheduler; the last command applies both values immediately.

Successful output looks like this:

net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

Debian’s sysctl files are read from /etc/sysctl.d/; the Debian Reference documentation explains this configuration layout.

Step 4: Check the queue on the active interface

Changing net.core.default_qdisc sets the default for interfaces created later, while an interface that is already up may still have its previous queueing discipline.

MAIN_IFACE=$(ip route show default | awk '/^default/ {print $5; exit}')
printf '%s\n' "$MAIN_IFACE"
tc qdisc show dev "$MAIN_IFACE"

The first line should print the device used by the default route, such as ens3 or eth0. If the qdisc is not fq, apply it for the current boot:

sudo tc qdisc replace dev "$MAIN_IFACE" root fq
tc qdisc show dev "$MAIN_IFACE"

Look for qdisc fq in the result:

ens3
qdisc fq 0: root refcnt 2 limit 10000p buckets 1024

The interface name and queue details differ between VPS images. The tc change is runtime state and may be lost if the interface is recreated; the net.core.default_qdisc setting will apply again during the next boot. If tc is missing, install Debian’s iproute2 package with sudo apt-get update && sudo apt-get install -y iproute2 and repeat the check.

Verify BBR on Debian 11

Run one final check to confirm the active algorithm, saved values, available BBR support, and qdisc on the main network interface.

MAIN_IFACE=$(ip route show default | awk '/^default/ {print $5; exit}')
sysctl net.ipv4.tcp_congestion_control net.core.default_qdisc
sysctl net.ipv4.tcp_available_congestion_control
grep -Ev '^[[:space:]]*(#|$)' /etc/sysctl.d/99-bbr.conf
tc qdisc show dev "$MAIN_IFACE"

You want tcp_congestion_control = bbr, default_qdisc = fq, bbr in the available list, both lines from 99-bbr.conf, and qdisc fq for the active interface. These settings affect new TCP connections, so reconnect SSH clients or restart long-lived services before comparing network behavior. The Linux kernel IP sysctl reference describes the TCP controls involved.

Troubleshooting

modprobe: FATAL: Module tcp_bbr not found

The running kernel may lack the BBR module, or its module package may not match the kernel. First check sysctl net.ipv4.tcp_available_congestion_control; if bbr is absent, install Debian’s standard kernel meta-package and reboot into it:

sudo apt-get update
sudo apt-get install -y linux-image-amd64
sudo reboot

After reconnecting, run Step 2 again. If the VPS boots a provider-managed custom kernel, the standard package may not be the kernel in use; ask the provider for a Debian 11 kernel with BBR support.

sysctl: cannot set net.ipv4.tcp_congestion_control

The sysctl file was loaded before BBR became available. Run sudo modprobe tcp_bbr, confirm that bbr appears in the available list, and reload the saved file:

sudo sysctl -p /etc/sysctl.d/99-bbr.conf

If the error returns after reboot, check that /etc/modules-load.d/tcp-bbr.conf contains exactly tcp_bbr.

tc qdisc show still reports fq_codel

The default scheduler value does not necessarily replace the qdisc already attached to an existing interface. Run the tc qdisc replace command from Step 4 with the actual default-route interface, then check the result again.

BBR is active until the next reboot

Inspect both persistent files and confirm that the rebooted system is using the same kernel family shown by uname -r:

cat /etc/modules-load.d/tcp-bbr.conf
cat /etc/sysctl.d/99-bbr.conf
sudo systemctl restart systemd-modules-load
sudo sysctl -p /etc/sysctl.d/99-bbr.conf

If BBR still disappears, the VPS kernel or boot policy may prevent module loading. Use the VPS control panel console while checking the boot messages, or request a supported Debian kernel from the provider.

FAQ

Does BBR require a firewall rule?

No. BBR changes TCP behavior inside the kernel and does not create a listening service or open an inbound port. Keep your existing SSH and application firewall rules unchanged.

Will BBR make every download faster?

Not necessarily. It can improve how a sender uses some congested paths, but the remote server, route, transfer size, and VPS bandwidth limit still matter. Compare the service you care about over multiple runs.

Does enabling BBR change existing connections?

The algorithm is selected when TCP connections are created. Reconnect SSH and restart persistent services before evaluating the change; already-open sessions may retain their original state.

How do I return to CUBIC?

Change net.ipv4.tcp_congestion_control = bbr to cubic in /etc/sysctl.d/99-bbr.conf, then run sudo sysctl -p /etc/sysctl.d/99-bbr.conf. You can leave the module-load file in place because loading tcp_bbr does not select it as the active algorithm.

Samrat Ghosh
Written by

Samrat Ghosh

Founder & Infrastructure Engineer

Samrat Ghosh is the founder of VPSLake, where he builds and runs the remote desktop and VPS hosting infrastructure the company is built on. He writes hands-on guides about RDP, Windows Server, VPS management and secure remote access - the practical documentation he wishes had…

Previous Article

Keep Programs Running After Closing RDP: Safe Steps

Next Article

Citrix vs RDP: Differences, Costs and Which to Use

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Subscribe to our Newsletter

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨