{"id":975,"date":"2026-11-01T03:00:00","date_gmt":"2026-11-01T03:00:00","guid":{"rendered":"https:\/\/vpslake.com\/blog\/?p=975"},"modified":"2026-11-01T03:00:00","modified_gmt":"2026-11-01T03:00:00","slug":"enable-bbr-rocky-linux-8","status":"publish","type":"post","link":"https:\/\/vpslake.com\/blog\/2026\/11\/01\/enable-bbr-rocky-linux-8\/","title":{"rendered":"How to Enable BBR on Rocky Linux 8 (Step-by-Step)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Enable BBR on Rocky Linux 8 to use a modern TCP congestion-control algorithm with the <code>fq<\/code> packet scheduler. You can apply it to a fresh VPS in about five minutes, keep the setting after reboots, and confirm the queue attached to the live network interface.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>A Rocky Linux 8 VPS, preferably fully updated, with a 4.9 or newer kernel. Rocky Linux 8 normally uses a 4.18-series kernel.<\/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 install kernel packages, load modules, write under <code>\/etc<\/code>, and change the network queueing discipline. An unprivileged container may not allow these 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, use a <a href=\"https:\/\/vpslake.com\/buy-vps\">Linux VPS from VPSLake<\/a> and install Rocky Linux 8.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">BBR changes how TCP estimates available capacity and paces packets; it does not raise your VPS plan\u2019s bandwidth limit. Your route, the remote peer, and the application determine whether it helps.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Confirm Rocky Linux 8 and inspect the current TCP state<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Identify the release and running kernel before installing a module so you do not mix packages for a different image or kernel.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/etc\/rocky-release\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 release should identify Rocky Linux 8, and the kernel should normally begin with <code>4.18<\/code>. A typical installation starts with <code>cubic<\/code>; BBR may already be listed if the matching module is present.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Rocky Linux release 8.10 (Green Obsidian)\n4.18.0-...el8_...x86_64\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\">Minor versions, kernel suffixes, and the algorithm order vary. Keep the provider\u2019s newer kernel if it is working; the important checks are that it is at least 4.9 and exposes BBR.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Install and load the Rocky Linux BBR module<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">On the EL8 kernel, BBR can be supplied by the extra kernel modules package. Install the package that matches the kernel currently running, then load <code>tcp_bbr<\/code> before selecting it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf install -y \"kernel-modules-extra-$(uname -r)\"\nsudo modprobe tcp_bbr\nsysctl net.ipv4.tcp_available_congestion_control<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The final command 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 BBR was already available, the install confirms the module package and <code>modprobe<\/code> simply leaves the module ready. Using the exact running-kernel package avoids installing modules that cannot be used until a later reboot.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Save BBR settings for future boots<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Keep the module request and sysctl values in small, separate files so Rocky Linux can restore both pieces without changing unrelated kernel tuning.<\/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-rocky-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-rocky-bbr.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first file asks the boot-time module loader to prepare BBR. The second selects BBR for new TCP connections and makes <code>fq<\/code> the default queueing discipline; the final command applies the two values immediately.<\/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\">The <a href=\"https:\/\/docs.redhat.com\/en\/documentation\/red_hat_enterprise_linux\/8\/html\/considerations_in_adopting_rhel_8\/networking_considerations-in-adopting-rhel-8\" target=\"_blank\" rel=\"noopener\">RHEL 8 networking documentation<\/a> explains the BBR support in the compatible kernel, and Rocky Linux 8 follows the same configuration layout.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Put <code>fq<\/code> on the interface already carrying traffic<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Changing <code>net.core.default_qdisc<\/code> affects interfaces initialized later; inspect the existing default-route interface and replace its current root queue if it still uses <code>fq_codel<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MAIN_IFACE=$(ip route show default | awk '\/^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 line should print an interface such as <code>ens3<\/code> or <code>eth0<\/code>. If the last command does not show <code>qdisc fq<\/code>, apply <code>fq<\/code> 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 a result containing <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\">To retain the per-interface queue when NetworkManager recreates the link, identify the active profile and save <code>root fq<\/code> there:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nmcli connection show --active\nsudo nmcli connection modify \"YOUR_CONNECTION_NAME\" tc.qdiscs 'root fq'\nsudo nmcli connection up \"YOUR_CONNECTION_NAME\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Replace <code>YOUR_CONNECTION_NAME<\/code> with the profile name shown by the first command. The final command can briefly interrupt SSH, so use the VPS control panel console or schedule this change during maintenance if the connection cannot drop.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Red Hat\u2019s <a href=\"https:\/\/docs.redhat.com\/en\/documentation\/red_hat_enterprise_linux\/8\/html\/configuring_and_managing_networking\/linux-traffic-control_configuring-and-managing-networking\" target=\"_blank\" rel=\"noopener\">RHEL 8 traffic-control guide<\/a> documents the temporary <code>tc<\/code> method and the persistent NetworkManager profile option.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verify BBR on Rocky Linux 8<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run the complete check after the settings are applied. It confirms the active algorithm, saved files, module availability, and queue on the interface used by the default route.<\/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-rocky-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-rocky-bbr.conf<\/code>, the line <code>tcp_bbr<\/code>, and <code>qdisc fq<\/code> on the active device. These values apply to new TCP connections, so reconnect SSH or restart a long-running service before comparing traffic.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>net.ipv4.tcp_congestion_control = bbr\nnet.core.default_qdisc = fq\nnet.ipv4.tcp_available_congestion_control = reno cubic bbr\nnet.core.default_qdisc = fq\nnet.ipv4.tcp_congestion_control = bbr\ntcp_bbr\nqdisc fq 0: root refcnt 2 limit 10000p buckets 1024<\/code><\/pre>\n\n\n\n<aside class=\"vl-element vl-cta-banner\" aria-label=\"Tune Rocky Linux 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 Rocky Linux networking<\/h3>\n\t\t<p class=\"vl-cta-banner__text\">Run Rocky Linux 8 workloads on a VPS ready for persistent TCP network tuning.<\/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>No match for argument: kernel-modules-extra-...<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The repository metadata may not contain a module package for the older kernel currently booted, or the VPS may use a provider-built kernel. Install the generic package, reboot into the newest Rocky kernel, and retry Step 2:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf install -y kernel-modules-extra\nsudo reboot<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After reconnecting, run <code>uname -r<\/code>, then <code>sudo modprobe tcp_bbr<\/code>. If the module is still unavailable, ask the provider for a standard Rocky Linux 8 kernel with BBR support instead of forcing an unrelated module package.<\/p>\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 still cannot see the BBR module. Check the available algorithms first; if <code>bbr<\/code> is absent, confirm that the <code>kernel-modules-extra<\/code> package matches <code>uname -r<\/code>, then reboot into the kernel for which it was installed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rpm -q \"kernel-modules-extra-$(uname -r)\"\nsysctl net.ipv4.tcp_available_congestion_control<\/code><\/pre>\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 was registered. Load the module, verify 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-rocky-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> and that the file name has not been replaced by another image-management tool.<\/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 qdisc value does not replace the queue already attached to an existing interface. Repeat Step 4 with the real default-route device; if it changes back after a NetworkManager restart, save <code>root fq<\/code> in the active connection profile. If <code>tc<\/code> itself is missing, install the Rocky Linux <code>iproute<\/code> package first:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf install -y iproute<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Does BBR require a firewall rule?<\/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 rules as they are.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why must the queue be <code>fq<\/code> instead of <code>fq_codel<\/code>?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">BBR paces packets, and <code>fq<\/code> is designed to work with that pacing model. Rocky\u2019s BBR guidance recommends explicitly using <code>fq<\/code>; setting the default alone may not change a queue already attached to a live interface.<\/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. <code>net.ipv4.tcp_congestion_control<\/code> applies only to TCP. UDP applications need their own rate-control behavior, so enabling BBR does not change their packet handling.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can I return to CUBIC without rebooting?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes. Change the congestion-control value in <code>\/etc\/sysctl.d\/99-rocky-bbr.conf<\/code> to <code>cubic<\/code>, then run <code>sudo sysctl -p \/etc\/sysctl.d\/99-rocky-bbr.conf<\/code>. You can leave <code>tcp_bbr<\/code> in the modules-load file because loading the module does not make it 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 require a firewall rule?\", \"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 rules as they are.\"}}, {\"@type\": \"Question\", \"name\": \"Why must the queue be `fq` instead of `fq_codel`?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"BBR paces packets, and `fq` is designed to work with that pacing model. Rocky\u2019s BBR guidance recommends explicitly using `fq`; setting the default alone may not change a queue already attached to a live interface.\"}}, {\"@type\": \"Question\", \"name\": \"Does BBR tune UDP traffic too?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. `net.ipv4.tcp_congestion_control` applies only to TCP. UDP applications need their own rate-control behavior, so enabling BBR does not change their packet handling.\"}}, {\"@type\": \"Question\", \"name\": \"Can I return to CUBIC without rebooting?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Yes. Change the congestion-control value in `\/etc\/sysctl.d\/99-rocky-bbr.conf` to `cubic`, then run `sudo sysctl -p \/etc\/sysctl.d\/99-rocky-bbr.conf`. You can leave `tcp_bbr` in the modules-load file because loading the module does not make it the active algorithm.\"}}]}<\/script>\n\n","protected":false},"excerpt":{"rendered":"Learn how to enable bbr on rocky linux 8, load its kernel module, persist fq settings, verify the live qdisc, and fix common VPS errors on your VPS.","protected":false},"author":1,"featured_media":976,"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,105,115],"class_list":["post-975","post","type-post","status-publish","format-standard","has-post-thumbnail","category-guides","category-vps-hosting","tag-bbr","tag-linux-networking","tag-rocky-linux-8","tag-vps-tuning","cs-entry"],"_links":{"self":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/975","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=975"}],"version-history":[{"count":1,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/975\/revisions"}],"predecessor-version":[{"id":3830,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/975\/revisions\/3830"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media\/976"}],"wp:attachment":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media?parent=975"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/categories?post=975"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/tags?post=975"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}