{"id":977,"date":"2026-11-01T09:00:00","date_gmt":"2026-11-01T09:00:00","guid":{"rendered":"https:\/\/vpslake.com\/blog\/?p=977"},"modified":"2026-11-01T09:00:00","modified_gmt":"2026-11-01T09:00:00","slug":"enable-bbr-ubuntu-22-04","status":"publish","type":"post","link":"https:\/\/vpslake.com\/blog\/2026\/11\/01\/enable-bbr-ubuntu-22-04\/","title":{"rendered":"How to Enable BBR on Ubuntu 22.04 (Step-by-Step)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Enable BBR on Ubuntu 22.04 to use a modern TCP congestion-control algorithm with the <code>fq<\/code> 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>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 <code>tcp_bbr<\/code> module.<\/li>\n\n\n<li>SSH access as <code>root<\/code>, or a normal user with working <code>sudo<\/code> privileges.<\/li>\n\n\n<li>Permission to load kernel modules and write files under <code>\/etc<\/code>; an unprivileged container may deny one or both operations.<\/li>\n\n\n<li>No domain, web server, extra RAM, or extra disk is needed because BBR is a kernel-level TCP setting.<\/li>\n\n\n<li>If you need the server first, choose a <a href=\"https:\/\/vpslake.com\/buy-vps\">Linux VPS from VPSLake<\/a> and install Ubuntu 22.04.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">BBR changes how TCP estimates available capacity and paces packets. It cannot raise your VPS plan\u2019s bandwidth limit, and the result depends on the route, remote peer, and workload.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Confirm Ubuntu 22.04 and inspect TCP<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Check the release and running kernel before changing sysctl values so a provider image or custom kernel does not surprise you.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>. \/etc\/os-release &amp;&amp; printf '%s\\n' \"$PRETTY_NAME\"\nuname -r\nsysctl net.ipv4.tcp_available_congestion_control\nsysctl net.ipv4.tcp_congestion_control<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line should identify Ubuntu 22.04 LTS, and a standard Server installation normally reports a <code>5.15<\/code> kernel. A fresh system commonly uses <code>cubic<\/code>; BBR may be absent from the available list until its module is loaded.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Ubuntu 22.04.5 LTS\n5.15.0-...-generic\nnet.ipv4.tcp_available_congestion_control = reno cubic\nnet.ipv4.tcp_congestion_control = cubic<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Load BBR for the current boot<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The kernel must register BBR before a sysctl can select it, so load the module and inspect the available algorithms in the same session.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo modprobe tcp_bbr\nsysctl net.ipv4.tcp_available_congestion_control<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The result should contain <code>bbr<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>net.ipv4.tcp_available_congestion_control = reno cubic bbr<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If <code>bbr<\/code> was already listed, <code>modprobe<\/code> simply confirms that the current kernel can use it. The exact order of the names is not important.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Save the settings for future boots<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo tee \/etc\/modules-load.d\/tcp-bbr.conf &gt;\/dev\/null &lt;&lt;'EOF'\ntcp_bbr\nEOF\nsudo tee \/etc\/sysctl.d\/90-tcp-bbr-ubuntu22.conf &gt;\/dev\/null &lt;&lt;'EOF'\nnet.core.default_qdisc = fq\nnet.ipv4.tcp_congestion_control = bbr\nEOF\nsudo sysctl -p \/etc\/sysctl.d\/90-tcp-bbr-ubuntu22.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first file tells systemd to load <code>tcp_bbr<\/code> during later boots. The second selects BBR for new TCP connections and chooses fair queueing as the default scheduler; <code>sysctl -p<\/code> applies the values now.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Successful output is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>net.core.default_qdisc = fq\nnet.ipv4.tcp_congestion_control = bbr<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ubuntu reads the local module list from <code>\/etc\/modules-load.d\/<\/code>; its <a href=\"https:\/\/manpages.ubuntu.com\/manpages\/jammy\/man5\/modules-load.d.5.html\" target=\"_blank\" rel=\"noopener\">Jammy <code>modules-load.d<\/code> documentation<\/a> describes the one-module-per-line format. The kernel\u2019s <a href=\"https:\/\/docs.kernel.org\/networking\/ip-sysctl.html\" target=\"_blank\" rel=\"noopener\">IP sysctl reference<\/a> explains that <code>tcp_congestion_control<\/code> selects the algorithm for new connections.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Check the queue on the live network interface<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Changing <code>net.core.default_qdisc<\/code> sets the default for interfaces created later, but the interface already carrying your SSH session can retain another root queue.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ip -o route show default\nMAIN_IFACE=$(ip -o route show default | awk '{print $5; exit}')\nprintf '%s\\n' \"$MAIN_IFACE\"\ntc qdisc show dev \"$MAIN_IFACE\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The route line identifies the default device, often <code>ens3<\/code> or <code>eth0<\/code>. If the last command does not show <code>qdisc fq<\/code>, replace the live root queue for the current boot:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo tc qdisc replace dev \"$MAIN_IFACE\" root fq\ntc qdisc show dev \"$MAIN_IFACE\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The second command should include <code>qdisc fq<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ens3\nqdisc fq 0: root refcnt 2 limit 10000p buckets 1024<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The interface name and queue details vary between VPS images. The <code>tc<\/code> replacement is runtime state and can be lost if the interface is recreated or the server reboots. The saved <code>default_qdisc<\/code> 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verify BBR on Ubuntu 22.04<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run one final set of checks to confirm the live algorithm, saved file, module availability, and queue attached to the default-route interface.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MAIN_IFACE=$(ip -o route show default | awk '{print $5; exit}')\nsysctl net.ipv4.tcp_congestion_control net.core.default_qdisc\nsysctl net.ipv4.tcp_available_congestion_control\ngrep -Ev '^[[:space:]]*(#|$)' \/etc\/sysctl.d\/90-tcp-bbr-ubuntu22.conf\ngrep -Fx 'tcp_bbr' \/etc\/modules-load.d\/tcp-bbr.conf\ntc qdisc show dev \"$MAIN_IFACE\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You want <code>tcp_congestion_control = bbr<\/code>, <code>default_qdisc = fq<\/code>, <code>bbr<\/code> in the available list, both assignments from the saved file, the line <code>tcp_bbr<\/code>, and <code>qdisc fq<\/code> on the active device. These settings apply to new TCP connections, so reconnect SSH or restart a long-lived service before comparing traffic.<\/p>\n\n\n\n<aside class=\"vl-element vl-cta-banner\" aria-label=\"Tune Ubuntu TCP networking\">\n\t<div class=\"vl-cta-banner__content\">\n\t\t<p class=\"vl-cta-banner__eyebrow\">Linux VPS<\/p>\n\t\t<h3 class=\"vl-cta-banner__title\">Tune Ubuntu TCP networking<\/h3>\n\t\t<p class=\"vl-cta-banner__text\">Run Ubuntu 22.04 workloads on a VPS ready for persistent BBR settings.<\/p>\n\t<\/div>\n\t<a class=\"vl-cta-banner__button\" href=\"\/buy-vps\" aria-label=\"View Linux VPS plans\">View Linux VPS plans<\/a>\n<\/aside>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><code>modprobe: FATAL: Module tcp_bbr not found<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The running kernel may not include BBR, or its matching module package may be missing. Check the algorithm list first; if <code>bbr<\/code> is absent, install Ubuntu\u2019s generic kernel package and reboot into it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sysctl net.ipv4.tcp_available_congestion_control\nsudo apt-get update\nsudo apt-get install -y linux-generic\nsudo reboot<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>sysctl: cannot set net.ipv4.tcp_congestion_control<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The sysctl file was applied before BBR became available, or the running kernel does not support it. Load the module, confirm that <code>bbr<\/code> appears, and reload the saved file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo modprobe tcp_bbr\nsysctl net.ipv4.tcp_available_congestion_control\nsudo sysctl -p \/etc\/sysctl.d\/90-tcp-bbr-ubuntu22.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If it fails again after reboot, check that <code>\/etc\/modules-load.d\/tcp-bbr.conf<\/code> contains exactly <code>tcp_bbr<\/code> and that <code>uname -r<\/code> still shows the expected Ubuntu kernel.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>tc qdisc show<\/code> still reports <code>fq_codel<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The default scheduler value does not necessarily replace the queue already attached to an existing interface. Run the <code>tc qdisc replace<\/code> command from Step 4 with the actual default-route device, then check the output again.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">BBR returns to <code>cubic<\/code> after reboot<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">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:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>grep -RnsE 'tcp_congestion_control|default_qdisc' \/etc\/sysctl.conf \/etc\/sysctl.d \/usr\/lib\/sysctl.d 2&gt;\/dev\/null\nsudo systemctl restart systemd-modules-load\nsudo sysctl -p \/etc\/sysctl.d\/90-tcp-bbr-ubuntu22.conf\nsysctl net.ipv4.tcp_available_congestion_control net.ipv4.tcp_congestion_control<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Keep the local file name beginning with <code>90-<\/code> so it loads after many vendor defaults. If the provider kernel does not expose BBR, install a supported Ubuntu kernel or contact the provider.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Does BBR increase the bandwidth of my VPS?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I need a firewall rule for BBR?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does BBR change UDP traffic?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. <code>net.ipv4.tcp_congestion_control<\/code> applies to TCP only. UDP software must implement its own rate control, so enabling BBR does not tune UDP streams.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How do I switch back to CUBIC?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Edit <code>\/etc\/sysctl.d\/90-tcp-bbr-ubuntu22.conf<\/code>, change the congestion-control value to <code>cubic<\/code>, and run <code>sudo sysctl -p \/etc\/sysctl.d\/90-tcp-bbr-ubuntu22.conf<\/code>. You can leave the module-load file in place because loading <code>tcp_bbr<\/code> does not select it as the active algorithm.<\/p>\n\n\n\n<script type=\"application\/ld+json\">{\"@context\": \"https:\/\/schema.org\", \"@type\": \"FAQPage\", \"mainEntity\": [{\"@type\": \"Question\", \"name\": \"Does BBR increase the bandwidth of my VPS?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"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.\"}}, {\"@type\": \"Question\", \"name\": \"Do I need a firewall rule for BBR?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"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.\"}}, {\"@type\": \"Question\", \"name\": \"Does BBR change UDP traffic?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"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.\"}}, {\"@type\": \"Question\", \"name\": \"How do I switch back to CUBIC?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"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.\"}}]}<\/script>\n\n","protected":false},"excerpt":{"rendered":"Learn how to enable bbr on ubuntu 22.04, persist the setting with fq, verify the live network queue, and fix common Ubuntu VPS kernel errors.","protected":false},"author":1,"featured_media":978,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_singular_sidebar":"","csco_page_header_type":"","csco_page_load_nextpost":"","footnotes":""},"categories":[5,9],"tags":[113,114,101,115],"class_list":["post-977","post","type-post","status-publish","format-standard","has-post-thumbnail","category-guides","category-vps-hosting","tag-bbr","tag-linux-networking","tag-ubuntu-22-04","tag-vps-tuning","cs-entry"],"_links":{"self":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/977","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/comments?post=977"}],"version-history":[{"count":1,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/977\/revisions"}],"predecessor-version":[{"id":3835,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/977\/revisions\/3835"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media\/978"}],"wp:attachment":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media?parent=977"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/categories?post=977"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/tags?post=977"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}