{"id":979,"date":"2026-11-01T13:00:00","date_gmt":"2026-11-01T13:00:00","guid":{"rendered":"https:\/\/vpslake.com\/blog\/?p=979"},"modified":"2026-11-01T13:00:00","modified_gmt":"2026-11-01T13:00:00","slug":"enable-bbr-ubuntu-24-04","status":"publish","type":"post","link":"https:\/\/vpslake.com\/blog\/2026\/11\/01\/enable-bbr-ubuntu-24-04\/","title":{"rendered":"How to Enable BBR on Ubuntu 24.04 (Step-by-Step)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">To enable BBR on Ubuntu 24.04, load the kernel module, select BBR with <code>sysctl<\/code>, and pair it with the <code>fq<\/code> queueing discipline. This takes about five minutes and leaves you with a reboot-safe configuration without opening another 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 24.04 LTS (Noble Numbat) VPS; the original release uses a 6.8 kernel, although cloud and HWE kernels may be newer.<\/li>\n\n\n<li>SSH access as <code>root<\/code>, or a normal account with working <code>sudo<\/code> privileges.<\/li>\n\n\n<li>Permission to load kernel modules and write files below <code>\/etc<\/code>; an unprivileged container may not provide those capabilities.<\/li>\n\n\n<li>No domain, web server, extra RAM, or extra disk is required 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 24.04.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">BBR changes TCP congestion control and packet pacing; it cannot raise your plan&#8217;s bandwidth limit. The result depends on the route, the remote peer, and the application making the connection.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Confirm Ubuntu 24.04 and inspect the current TCP settings<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Check the release and running kernel before changing anything 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 24.04 LTS, and the kernel will normally begin with <code>6.8<\/code> on the original Noble image. A fresh system commonly selects <code>cubic<\/code>; BBR may already be listed if the provider kernel has registered it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Ubuntu 24.04.x LTS\n6.8.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\">Kernel patch numbers and the available algorithm order vary. Do not replace a working newer cloud or HWE kernel just to match the sample output.<\/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 Ubuntu can select it through <code>sysctl<\/code>, so load the module and inspect the available algorithms immediately.<\/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 second command should now include <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 present, <code>modprobe<\/code> simply confirms that the running 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 BBR and <code>fq<\/code> across reboots<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Keep the module request and kernel parameters in separate files so you can audit or remove this tuning without overwriting Ubuntu&#8217;s other 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\/99-tcp-bbr.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\/99-tcp-bbr.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first file asks <code>systemd-modules-load<\/code> to load BBR during later boots. The second selects BBR for new TCP connections and sets fair queueing as the default scheduler; the final command applies both values now.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Successful output looks like this:<\/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 24.04&#8217;s release kernel is 6.8, but later point updates and hardware-enable stacks can use a newer supported kernel. The <a href=\"https:\/\/documentation.ubuntu.com\/release-notes\/24.04\/\" target=\"_blank\" rel=\"noopener\">Ubuntu 24.04 release notes<\/a> explain the Noble kernel baseline, while the <a href=\"https:\/\/docs.kernel.org\/networking\/ip-sysctl.html\" target=\"_blank\" rel=\"noopener\">Linux kernel IP sysctl reference<\/a> documents the TCP controls used here.<\/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\"><code>net.core.default_qdisc<\/code> controls the default for interfaces created later; <code>tc<\/code> shows whether the interface already carrying your SSH traffic is using <code>fq<\/code> right now.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MAIN_IFACE=$(ip -o route show default | awk '$1 == \"default\" {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 first command should print a device such as <code>ens3<\/code> or <code>eth0<\/code>. If the last command reports <code>fq_codel<\/code> or another root queue, replace it 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\">Look for <code>qdisc fq<\/code> in the result:<\/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 differ between VPS images. The <code>tc<\/code> replacement is runtime state; the saved <code>default_qdisc<\/code> value is what the kernel uses when the interface is initialized again. Do not bring the interface down 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 24.04<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run one final check to confirm the active algorithm, persistent file, module availability, and qdisc on the default-route interface.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MAIN_IFACE=$(ip -o route show default | awk '$1 == \"default\" {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\/99-tcp-bbr.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 <code>99-tcp-bbr.conf<\/code>, the line <code>tcp_bbr<\/code>, and <code>qdisc fq<\/code> for the active device. These values govern 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 24.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 lack its matching extra modules package, or the provider may be using a custom kernel without BBR. Install the modules for the current Ubuntu kernel and try again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update\nsudo apt install -y linux-modules-extra-$(uname -r)\nsudo modprobe tcp_bbr<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If APT cannot find that exact package, install Ubuntu&#8217;s generic kernel, reboot, and repeat Step 2:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install -y linux-generic\nsudo reboot<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the server still boots a provider-managed kernel, ask the provider for an Ubuntu 24.04 kernel with BBR support rather than forcing an unrelated module 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\">BBR was not registered when the sysctl file was applied. Run <code>sudo modprobe tcp_bbr<\/code>, confirm that <code>bbr<\/code> appears in <code>net.ipv4.tcp_available_congestion_control<\/code>, and reload the saved file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo sysctl -p \/etc\/sysctl.d\/99-tcp-bbr.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the error returns after a reboot, check that <code>\/etc\/modules-load.d\/tcp-bbr.conf<\/code> contains exactly <code>tcp_bbr<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>tc: command not found<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The minimal image is missing <code>iproute2<\/code>, which supplies both <code>ip<\/code> and <code>tc<\/code>. Install it, then repeat Step 4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update\nsudo apt install -y iproute2<\/code><\/pre>\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\">Changing the default scheduler 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 real default-route interface; if the command returns <code>Operation not permitted<\/code>, the VPS does not grant the traffic-control capability and the provider must change it from the host.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Does enabling BBR require a firewall rule?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. BBR is a kernel TCP setting, not a daemon, so it does not listen on a port or change your existing UFW policy. Keep only the inbound rules your applications actually need.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Will BBR make every download faster?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Not necessarily. BBR can improve how TCP uses some congested paths, but the remote server, route, transfer size, and VPS bandwidth cap still matter. Compare the application you care about over several representative connections.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does BBR affect UDP applications?<\/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 or congestion control, so this setting does not tune DNS, WireGuard, VoIP, or game traffic.<\/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\">Change <code>net.ipv4.tcp_congestion_control = bbr<\/code> to <code>cubic<\/code> in <code>\/etc\/sysctl.d\/99-tcp-bbr.conf<\/code>, then run <code>sudo sysctl -p \/etc\/sysctl.d\/99-tcp-bbr.conf<\/code>. You can leave <code>tcp_bbr<\/code> in the module-load file because loading the module 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 enabling BBR require a firewall rule?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. BBR is a kernel TCP setting, not a daemon, so it does not listen on a port or change your existing UFW policy. Keep only the inbound rules your applications actually need.\"}}, {\"@type\": \"Question\", \"name\": \"Will BBR make every download faster?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Not necessarily. BBR can improve how TCP uses some congested paths, but the remote server, route, transfer size, and VPS bandwidth cap still matter. Compare the application you care about over several representative connections.\"}}, {\"@type\": \"Question\", \"name\": \"Does BBR affect UDP applications?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. `net.ipv4.tcp_congestion_control` applies to TCP only. UDP software must implement its own rate or congestion control, so this setting does not tune DNS, WireGuard, VoIP, or game traffic.\"}}, {\"@type\": \"Question\", \"name\": \"How do I switch back to CUBIC?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Change `net.ipv4.tcp_congestion_control = bbr` to `cubic` in `\/etc\/sysctl.d\/99-tcp-bbr.conf`, then run `sudo sysctl -p \/etc\/sysctl.d\/99-tcp-bbr.conf`. You can leave `tcp_bbr` in the module-load file because loading the module does not select it as the active algorithm.\"}}]}<\/script>\n\n","protected":false},"excerpt":{"rendered":"Enable BBR on Ubuntu 24.04 with persistent kernel settings, fq queueing, live checks, and practical fixes for missing modules or reboot issues.","protected":false},"author":1,"featured_media":980,"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,102,115],"class_list":["post-979","post","type-post","status-publish","format-standard","has-post-thumbnail","category-guides","category-vps-hosting","tag-bbr","tag-linux-networking","tag-ubuntu-24-04","tag-vps-tuning","cs-entry"],"_links":{"self":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/979","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=979"}],"version-history":[{"count":1,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/979\/revisions"}],"predecessor-version":[{"id":3836,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/979\/revisions\/3836"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media\/980"}],"wp:attachment":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media?parent=979"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/categories?post=979"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/tags?post=979"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}