Enable BBR on Ubuntu 26.04 to make new TCP connections use a modern congestion-control algorithm and the fq packet scheduler. You can apply the change immediately and make it survive reboots in about five minutes without opening a new firewall port.
Prerequisites
- Ubuntu Server 26.04 LTS (Resolute Raccoon), using the normal generic kernel or another kernel newer than 4.9.
- SSH access as
root, or a normal user with workingsudoprivileges. - Permission to load kernel modules and write files below
/etc; an unprivileged container may not provide those capabilities. - 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, start with a Linux VPS from VPSLake and install Ubuntu 26.04.
BBR changes TCP pacing and capacity estimation; it does not increase the bandwidth limit attached to your VPS. The result depends on the route, the remote peer, and the application using TCP.
Step 1: Confirm Ubuntu 26.04 and inspect TCP
Check the release and running kernel before changing sysctl values so you do not tune a different image or a provider-supplied kernel unexpectedly.
. /etc/os-release && printf '%s\n' "$PRETTY_NAME"
uname -r
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control
The first line should identify Ubuntu 26.04, and the release ships with a 7.0-series kernel in the standard stack. A fresh installation commonly uses cubic; BBR may already be listed if the kernel has registered it.
Ubuntu 26.04 LTS
7.0.0-...-generic
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 reproduce the sample output.
Step 2: Make BBR available to the running kernel
The kernel must register BBR before a sysctl can select it, so load the module only when the current algorithm list does not already contain it.
if ! sysctl -n net.ipv4.tcp_available_congestion_control | grep -qw bbr; then
sudo modprobe tcp_bbr
fi
sysctl net.ipv4.tcp_available_congestion_control
The final line should contain bbr:
net.ipv4.tcp_available_congestion_control = reno cubic bbr
If BBR was already listed, the conditional skips modprobe. The order of the algorithms is not important; the check proves that the running kernel can use BBR.
Step 3: Save BBR and fq for future boots
Keep the module request and sysctl values in separate drop-in files so Ubuntu can restore both pieces at boot without changing unrelated kernel tuning.
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 systemd-modules-load to prepare BBR during later boots. The second selects BBR for new TCP connections and sets fair queueing as the default scheduler; the final command applies those values now.
Successful output looks like this:
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Ubuntu supports persistent kernel parameters through /etc/sysctl.d/, and modules-load.d is the standard systemd location for a static list of modules to load at boot. The Ubuntu sysctl guidance and modules-load.d reference describe these configuration locations.
Step 4: Check the queue on the active network interface
net.core.default_qdisc controls the default for interfaces created later, but the interface already carrying your SSH session can still have another root queue.
MAIN_IFACE=$(ip -o route show default | awk '{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, often ens3 or eth0. If the final command does not show qdisc fq, replace the live root queue for the current boot:
sudo tc qdisc replace dev "$MAIN_IFACE" root fq
tc qdisc show dev "$MAIN_IFACE"
Look for a result similar to this:
ens3
qdisc fq 0: root refcnt 2 limit 10000p buckets 1024
Your interface name and queue details will differ. The tc replacement changes the active interface without opening a port, but it is runtime state; the saved default_qdisc value handles interface initialization on a later boot. Do not bring a NetworkManager or netplan connection down over SSH unless you have the VPS control panel console available.
Verify BBR on Ubuntu 26.04
Run the complete check below to prove that the active algorithm, persistent files, module availability, and live qdisc all agree.
MAIN_IFACE=$(ip -o route show default | awk '{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
grep -Fx 'tcp_bbr' /etc/modules-load.d/tcp-bbr.conf
tc qdisc show dev "$MAIN_IFACE"
You want tcp_congestion_control = bbr, default_qdisc = fq, bbr in the available list, both assignments from 99-bbr.conf, the line tcp_bbr, and qdisc fq for the active interface. These settings apply to new TCP connections, so reconnect SSH clients or restart a long-lived service before comparing network behavior.
The Linux kernel IP sysctl reference confirms that tcp_congestion_control selects the algorithm for new connections. BBR cannot guarantee faster traffic on every route, so compare the application and remote peers that matter to you.
Troubleshooting
modprobe: FATAL: Module tcp_bbr not found
The running kernel does not expose the BBR module, or the matching module package is missing. On a standard Ubuntu generic kernel, install the extra modules package for the kernel you are running, then try Step 2 again:
sudo apt update
sudo apt install -y linux-modules-extra-$(uname -r)
sudo modprobe tcp_bbr
If APT cannot find that exact package, the VPS may be using a provider-managed custom kernel. Ask the provider for a supported Ubuntu 26.04 generic kernel instead of installing a package built for a different kernel.
sysctl: cannot set net.ipv4.tcp_congestion_control
BBR was not available when the configuration was applied. Run Step 2, confirm that bbr appears in net.ipv4.tcp_available_congestion_control, and reload the saved file:
sudo sysctl -p /etc/sysctl.d/99-bbr.conf
If the error returns after a reboot, verify that /etc/modules-load.d/tcp-bbr.conf contains exactly tcp_bbr and that the VPS is booting the same kernel family you checked with uname -r.
tc: command not found
The minimal image is missing iproute2, which provides both ip and tc. Install it, then repeat Step 4:
sudo apt update
sudo apt install -y iproute2
RTNETLINK answers: Operation not permitted
The VPS is likely an unprivileged container without the capability needed to replace a qdisc. The TCP sysctl may still work, but the live fq queue cannot be changed inside that container; ask the provider for a full VPS or the required traffic-control permission.
FAQ
Does Ubuntu 26.04 need a special BBR patch?
No. The standard Ubuntu 26.04 kernel is new enough for BBR; the important checks are whether bbr appears in the available algorithm list and whether the live sysctl selects it. A custom provider kernel can still omit the module.
Why pair BBR with fq?
BBR estimates the path and paces TCP traffic, while fq provides fair per-flow queueing for that paced traffic. Setting the default qdisc is useful, but checking the existing interface matters because changing a default does not always replace a queue that is already attached.
Does BBR tune UDP traffic?
No. net.ipv4.tcp_congestion_control applies to TCP only. UDP applications need their own rate and congestion-control behavior, so enabling BBR does not change them.
How do I switch back 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.