Enable BBR on Ubuntu 22.04 to use a modern TCP congestion-control algorithm with the fq packet scheduler. You can apply it immediately, keep it after a reboot, and confirm the live interface in about five minutes without opening a new firewall port.
Prerequisites
- An Ubuntu Server 22.04 LTS (Jammy Jellyfish) VPS. The standard Ubuntu Server kernel is in the 5.15 series, and BBR requires a kernel that exposes the
tcp_bbrmodule. - SSH access as
root, or a normal user with workingsudoprivileges. - Permission to load kernel modules and write files under
/etc; an unprivileged container may deny one or both operations. - No domain, web server, extra RAM, or extra disk is needed because BBR is a kernel-level TCP setting.
- If you need the server first, choose a Linux VPS from VPSLake and install Ubuntu 22.04.
BBR changes how TCP estimates available capacity and paces packets. It cannot raise your VPS plan’s bandwidth limit, and the result depends on the route, remote peer, and workload.
Step 1: Confirm Ubuntu 22.04 and inspect TCP
Check the release and running kernel before changing sysctl values so a provider image or custom kernel does not surprise you.
. /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 22.04 LTS, and a standard Server installation normally reports a 5.15 kernel. A fresh system commonly uses cubic; BBR may be absent from the available list until its module is loaded.
Ubuntu 22.04.5 LTS
5.15.0-...-generic
net.ipv4.tcp_available_congestion_control = reno cubic
net.ipv4.tcp_congestion_control = cubic
Your point release, kernel revision, and algorithm order can differ. Keep a newer Ubuntu cloud or provider kernel if it is working; the important check is whether it provides BBR.
Step 2: Load BBR for the current boot
The kernel must register BBR before a sysctl can select it, so load the module and inspect the available algorithms in the same session.
sudo modprobe tcp_bbr
sysctl net.ipv4.tcp_available_congestion_control
The result should contain bbr:
net.ipv4.tcp_available_congestion_control = reno cubic bbr
If bbr was already listed, modprobe simply confirms that the current kernel can use it. The exact order of the names is not important.
Step 3: Save the settings for future boots
Store the module request and kernel parameters in separate Ubuntu configuration files so you can audit or remove this tuning without editing unrelated system settings.
sudo tee /etc/modules-load.d/tcp-bbr.conf >/dev/null <<'EOF'
tcp_bbr
EOF
sudo tee /etc/sysctl.d/90-tcp-bbr-ubuntu22.conf >/dev/null <<'EOF'
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF
sudo sysctl -p /etc/sysctl.d/90-tcp-bbr-ubuntu22.conf
The first file tells systemd to load tcp_bbr during later boots. The second selects BBR for new TCP connections and chooses fair queueing as the default scheduler; sysctl -p applies the values now.
Successful output is:
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Ubuntu reads the local module list from /etc/modules-load.d/; its Jammy modules-load.d documentation describes the one-module-per-line format. The kernel’s IP sysctl reference explains that tcp_congestion_control selects the algorithm for new connections.
Step 4: Check the queue on the live network interface
Changing net.core.default_qdisc sets the default for interfaces created later, but the interface already carrying your SSH session can retain another root queue.
ip -o route show default
MAIN_IFACE=$(ip -o route show default | awk '{print $5; exit}')
printf '%s\n' "$MAIN_IFACE"
tc qdisc show dev "$MAIN_IFACE"
The route line identifies the default device, often ens3 or eth0. If the last 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"
The second command should include qdisc fq:
ens3
qdisc fq 0: root refcnt 2 limit 10000p buckets 1024
The interface name and queue details vary between VPS images. The tc replacement is runtime state and can be lost if the interface is recreated or the server reboots. The saved default_qdisc value will be used when the interface is initialized again. Do not restart networking over SSH unless you have the VPS control panel console available.
Verify BBR on Ubuntu 22.04
Run one final set of checks to confirm the live algorithm, saved file, module availability, and queue attached to the default-route interface.
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/90-tcp-bbr-ubuntu22.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 the saved file, the line tcp_bbr, and qdisc fq on the active device. These settings apply to new TCP connections, so reconnect SSH or restart a long-lived service before comparing traffic.
Troubleshooting
modprobe: FATAL: Module tcp_bbr not found
The running kernel may not include BBR, or its matching module package may be missing. Check the algorithm list first; if bbr is absent, install Ubuntu’s generic kernel package and reboot into it:
sysctl net.ipv4.tcp_available_congestion_control
sudo apt-get update
sudo apt-get install -y linux-generic
sudo reboot
After reconnecting, run Step 2 again. If the VPS continues to boot a provider-managed custom kernel, ask the provider for an Ubuntu 22.04 kernel with BBR support instead of forcing an unrelated kernel package.
sysctl: cannot set net.ipv4.tcp_congestion_control
The sysctl file was applied before BBR became available, or the running kernel does not support it. Load the module, confirm that bbr appears, and reload the saved file:
sudo modprobe tcp_bbr
sysctl net.ipv4.tcp_available_congestion_control
sudo sysctl -p /etc/sysctl.d/90-tcp-bbr-ubuntu22.conf
If it fails again after reboot, check that /etc/modules-load.d/tcp-bbr.conf contains exactly tcp_bbr and that uname -r still shows the expected Ubuntu kernel.
tc qdisc show still reports fq_codel
The default scheduler value does not necessarily replace the queue already attached to an existing interface. Run the tc qdisc replace command from Step 4 with the actual default-route device, then check the output again.
BBR returns to cubic after reboot
Another sysctl file may be loaded later, or BBR was not loaded early enough. Search the active configuration and then reload the module and Ubuntu-specific file:
grep -RnsE 'tcp_congestion_control|default_qdisc' /etc/sysctl.conf /etc/sysctl.d /usr/lib/sysctl.d 2>/dev/null
sudo systemctl restart systemd-modules-load
sudo sysctl -p /etc/sysctl.d/90-tcp-bbr-ubuntu22.conf
sysctl net.ipv4.tcp_available_congestion_control net.ipv4.tcp_congestion_control
Keep the local file name beginning with 90- so it loads after many vendor defaults. If the provider kernel does not expose BBR, install a supported Ubuntu kernel or contact the provider.
FAQ
Does BBR increase the bandwidth of my VPS?
No. BBR changes TCP pacing and capacity estimation, but it cannot raise the network limit on your plan or make a slow remote server send faster. Evaluate the application and routes that matter to you rather than expecting every transfer to improve.
Do I need a firewall rule for BBR?
No. BBR changes TCP behavior inside the kernel and does not create a listening service or open an inbound port. Leave your existing SSH and application firewall policy unchanged.
Does BBR change UDP traffic?
No. net.ipv4.tcp_congestion_control applies to TCP only. UDP software must implement its own rate control, so enabling BBR does not tune UDP streams.
How do I switch back to CUBIC?
Edit /etc/sysctl.d/90-tcp-bbr-ubuntu22.conf, change the congestion-control value to cubic, and run sudo sysctl -p /etc/sysctl.d/90-tcp-bbr-ubuntu22.conf. You can leave the module-load file in place because loading tcp_bbr does not select it as the active algorithm.