{"id":981,"date":"2026-11-01T18:00:00","date_gmt":"2026-11-01T18:00:00","guid":{"rendered":"https:\/\/vpslake.com\/blog\/?p=981"},"modified":"2026-11-01T18:00:00","modified_gmt":"2026-11-01T18:00:00","slug":"enable-bbr-ubuntu-25-10","status":"publish","type":"post","link":"https:\/\/vpslake.com\/blog\/2026\/11\/01\/enable-bbr-ubuntu-25-10\/","title":{"rendered":"How to Enable BBR on Ubuntu 25.10 (Step-by-Step)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Enable BBR on Ubuntu 25.10 to make new TCP connections use a modern congestion-control algorithm and the <code>fq<\/code> packet scheduler. You will apply the change immediately, save it for future boots, and confirm the live network queue in about five minutes.<\/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 25.10 (Questing Quokka) VPS with a kernel newer than 4.9; the release normally uses the Linux 6.17 kernel.<\/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 under <code>\/etc<\/code>; an unprivileged container may not allow those operations.<\/li>\n\n\n<li>The <code>iproute2<\/code> package, which provides <code>ip<\/code> and <code>tc<\/code>, should be installed. No domain, web server, extra RAM, or extra disk is required.<\/li>\n\n\n<li>Ubuntu 25.10 is an interim release with a nine-month support window; if you are provisioning a new server, check the supported-release options with your provider first.<\/li>\n\n\n<li>If you need the server, start with a <a href=\"https:\/\/vpslake.com\/buy-vps\">Linux VPS from VPSLake<\/a> and choose Ubuntu 25.10 when available.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">BBR changes TCP pacing and capacity estimation; it does not increase the bandwidth limit of your plan. The result depends on the route, the remote peer, and the application generating traffic.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Inspect Ubuntu and the current TCP configuration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Check the release, running kernel, available algorithms, and <code>tc<\/code> command before changing anything so you know which kernel is actually handling the VPS network.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/etc\/os-release\nuname -r\nsysctl net.ipv4.tcp_available_congestion_control\nsysctl net.ipv4.tcp_congestion_control\ncommand -v tc<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On a standard Ubuntu 25.10 image, the release identifies Questing Quokka and the kernel begins with <code>6.17<\/code>. The active algorithm is usually <code>cubic<\/code>; <code>bbr<\/code> may already be listed if the module is built in or was loaded by the image.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PRETTY_NAME=\"Ubuntu 25.10\"\nVERSION_CODENAME=questing\n6.17.0-...-generic\nnet.ipv4.tcp_available_congestion_control = reno cubic\nnet.ipv4.tcp_congestion_control = cubic\n\/usr\/sbin\/tc<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Kernel suffixes and algorithm order vary by image and provider. Do not replace a working provider kernel just to reproduce the sample output.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Load BBR in the running kernel<\/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 first and then inspect the available list.<\/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 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 present, <code>modprobe<\/code> simply confirms that the running kernel can use it. Some Ubuntu kernels expose the algorithm without a separate line in <code>lsmod<\/code>, so the available-algorithm sysctl is the useful check rather than the module listing alone.<\/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 boot-time module request separate from the sysctl drop-in so you can audit or remove this tuning without editing Ubuntu\u2019s general configuration.<\/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-ubuntu-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-ubuntu-bbr.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first file tells systemd to request <code>tcp_bbr<\/code> during later boots. The second selects BBR for new TCP connections and sets fair queueing as the default scheduler; <code>sysctl -p<\/code> 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 reads local kernel-parameter drop-ins from <code>\/etc\/sysctl.d\/<\/code>. The <a href=\"https:\/\/documentation.ubuntu.com\/release-notes\/25.10\/\" target=\"_blank\" rel=\"noopener\">Ubuntu 25.10 release notes<\/a> also matter here because this release packages kernel modules in <code>linux-modules-&lt;version&gt;-&lt;flavor&gt;<\/code> packages rather than the older <code>linux-modules-extra-*<\/code> pattern.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Check the queue on the active interface<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>net.core.default_qdisc<\/code> sets the default for interfaces initialized later, while the interface already carrying your SSH session may still have another queueing discipline.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MAIN_IFACE=$(ip route show default | awk '\/^default\/ {print $5; exit}')\nprintf 'Default interface: %s\\n' \"$MAIN_IFACE\"\nsudo tc qdisc show dev \"$MAIN_IFACE\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line should print a device such as <code>ens3<\/code> or <code>eth0<\/code>. If the final command does not show <code>qdisc fq<\/code>, replace the live root queue without bringing the interface down:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo tc qdisc replace dev \"$MAIN_IFACE\" root fq\nsudo tc 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>Default interface: ens3\nqdisc fq 0: root refcnt 2 limit 10000p buckets 1024<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The device name and queue details differ between VPS images. The <code>tc<\/code> replacement is runtime state and can be lost when the interface is recreated; the saved <code>net.core.default_qdisc<\/code> value applies when the interface is initialized again. Do not restart the network profile 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 25.10<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run this final check to confirm that the algorithm is active, the configuration is saved, BBR is available, and <code>fq<\/code> is attached to the default-route interface.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MAIN_IFACE=$(ip route show default | awk '\/^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-ubuntu-bbr.conf\ngrep -Fx 'tcp_bbr' \/etc\/modules-load.d\/tcp-bbr.conf\nsudo tc 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-ubuntu-bbr.conf<\/code>, the line <code>tcp_bbr<\/code>, and <code>qdisc fq<\/code> for the active interface. The <a href=\"https:\/\/docs.kernel.org\/networking\/ip-sysctl.html\" target=\"_blank\" rel=\"noopener\">Linux kernel IP sysctl reference<\/a> notes that <code>tcp_congestion_control<\/code> selects the algorithm for new connections, so reconnect SSH clients 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 workloads on a VPS ready for persistent BBR and fq 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 does not have its matching BBR module installed, or the VPS is using a custom provider kernel. Ubuntu 25.10 places modules in a versioned <code>linux-modules<\/code> package, so try the package matching the kernel you are running:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get update\nsudo apt-get install --reinstall \"linux-modules-$(uname -r)\"\nsudo modprobe tcp_bbr<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If APT cannot find that exact package, a standard generic image may need the generic kernel meta-package instead:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get install -y linux-generic\nsudo reboot<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After reconnecting, run Step 2. For a provider-managed kernel, ask the provider for a kernel with BBR support rather than mixing an unrelated module package into the running kernel.<\/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. Load the module, confirm that <code>bbr<\/code> appears, and apply the dedicated file again:<\/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\/99-ubuntu-bbr.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the error returns after every reboot, check that <code>\/etc\/modules-load.d\/tcp-bbr.conf<\/code> contains exactly <code>tcp_bbr<\/code> and that the VPS is booting the kernel you inspected with <code>uname -r<\/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-get update\nsudo apt-get install -y iproute2<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>RTNETLINK answers: Operation not permitted<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The VPS is likely an unprivileged container without the <code>CAP_NET_ADMIN<\/code> capability required to replace a qdisc. The TCP sysctl may still work, but the live <code>fq<\/code> queue cannot be changed from inside that container; use a full VPS or ask the provider to enable the needed traffic-control capability.<\/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 how the kernel estimates path capacity and paces TCP packets, but it cannot raise the network limit attached to your plan. A remote server, congested route, or application limit can still be the bottleneck.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why is BBR available but not active?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Loading <code>tcp_bbr<\/code> only registers the algorithm with the kernel. The <code>net.ipv4.tcp_congestion_control = bbr<\/code> setting selects it for new TCP connections, so check both the live sysctl value and the saved drop-in.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does BBR tune UDP traffic too?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. The setting is specifically for TCP congestion control. UDP applications need their own rate-control behavior and are unaffected by this choice.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I need to reboot Ubuntu 25.10?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No reboot is required when <code>modprobe<\/code> and <code>sysctl -p<\/code> succeed; the running kernel uses the new values immediately. The files under <code>\/etc\/modules-load.d\/<\/code> and <code>\/etc\/sysctl.d\/<\/code> make the configuration available after a later reboot.<\/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 how the kernel estimates path capacity and paces TCP packets, but it cannot raise the network limit attached to your plan. A remote server, congested route, or application limit can still be the bottleneck.\"}}, {\"@type\": \"Question\", \"name\": \"Why is BBR available but not active?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Loading `tcp_bbr` only registers the algorithm with the kernel. The `net.ipv4.tcp_congestion_control = bbr` setting selects it for new TCP connections, so check both the live sysctl value and the saved drop-in.\"}}, {\"@type\": \"Question\", \"name\": \"Does BBR tune UDP traffic too?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. The setting is specifically for TCP congestion control. UDP applications need their own rate-control behavior and are unaffected by this choice.\"}}, {\"@type\": \"Question\", \"name\": \"Do I need to reboot Ubuntu 25.10?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No reboot is required when `modprobe` and `sysctl -p` succeed; the running kernel uses the new values immediately. The files under `\/etc\/modules-load.d\/` and `\/etc\/sysctl.d\/` make the configuration available after a later reboot.\"}}]}<\/script>\n\n","protected":false},"excerpt":{"rendered":"Learn how to enable bbr on ubuntu 25.10, persist fq and module loading, verify the live qdisc, and fix common VPS errors without opening network ports.","protected":false},"author":1,"featured_media":982,"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,103,115],"class_list":["post-981","post","type-post","status-publish","format-standard","has-post-thumbnail","category-guides","category-vps-hosting","tag-bbr","tag-linux-networking","tag-ubuntu-25-10","tag-vps-tuning","cs-entry"],"_links":{"self":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/981","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=981"}],"version-history":[{"count":1,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/981\/revisions"}],"predecessor-version":[{"id":3841,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/981\/revisions\/3841"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media\/982"}],"wp:attachment":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media?parent=981"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/categories?post=981"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/tags?post=981"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}