TCP BBR on a VPS: Enabling Modern Congestion Control for Faster Transfers

If your VPS transfers large files slowly, or throughput collapses whenever the network drops a packet, the default TCP congestion control algorithm is a likely culprit. Most Linux distributions still ship CUBIC, which was designed for a world where packet loss meant congestion. On modern high-bandwidth links, BBR — Google’s Bottleneck Bandwidth and Round-trip propagation time algorithm — models the actual bottleneck instead of treating every dropped packet as a signal to halve the sending rate. This article explains how to enable BBR on a VPS, how to verify it is active, and what results to expect on real workloads.

What BBR Changes Under the Hood

CUBIC probes for available bandwidth by increasing the send rate until packets drop, then backs off. BBR instead measures the bottleneck bandwidth and the minimum round-trip time continuously, and paces the sender to match. The practical effect: BBR keeps the pipe full without relying on loss as a signal, which produces dramatically better throughput on links with bufferbloat, on long-distance routes, and when other tenants on the same uplink cause occasional drops. The trade-off is slightly more bandwidth consumed by retransmissions in some loss-heavy scenarios, and no benefit at all if your bottleneck is local CPU or disk rather than the network.

Check Your Kernel First

BBR requires kernel 4.9+ as a module and 4.13+ for the fq qdisc integration. Almost every VPS image in production in 2026 — Ubuntu 22.04/24.04, Debian 12, Rocky 9, AlmaLinux 9 — ships a kernel well past that. Verify what you have before changing anything:

uname -r
# BBR available as a module?
modinfo tcp_bbr | head -5
# current congestion control
sysctl net.ipv4.tcp_congestion_control

If modinfo tcp_bbr returns nothing, your kernel was built without it — this is rare on mainstream distros but possible on heavily customized provider kernels. In that case the only options are a distro kernel update or a provider change; the kernel and feature details in our provider comparison table are worth checking before you commit to a VPS plan if you plan to run network-heavy workloads.

Enable BBR and the fq Qdisc

BBR is designed to work with the fq (fair queue) qdisc, which handles pacing. Enable both at runtime first, then make them permanent:

modprobe tcp_bbr
sysctl -w net.core.default_qdisc=fq
sysctl -w net.ipv4.tcp_congestion_control=bbr

To make the change survive a reboot, write it to /etc/sysctl.d/ and load the module at boot:

echo "net.core.default_qdisc=fq" >> /etc/sysctl.d/99-bbr.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.d/99-bbr.conf
echo "tcp_bbr" > /etc/modules-load.d/bbr.conf
sysctl --system

Confirm the change took effect:

sysctl net.ipv4.tcp_congestion_control
# expected: net.ipv4.tcp_congestion_control = bbr
sysctl net.core.default_qdisc
# expected: net.core.default_qdisc = fq
ss -Tin | head -10   # shows the congestion control in use per connection

The ss -Tin output lists cubic or bbr in the third column for established connections. Existing connections keep their old algorithm; new connections use BBR immediately. If you see bbr there, the kernel is using it.

Measure the Difference with iperf3

Never enable a kernel setting on faith — measure it. iperf3 is the standard tool for this, and you need a second server to test against (any VPS or a cloud instance works; a second VPS from a different provider gives the most honest cross-network numbers):

# on the remote test server
apt install -y iperf3 && iperf3 -s
# on your VPS, against CUBIC first
sysctl -w net.ipv4.tcp_congestion_control=cubic
iperf3 -c REMOTE_IP -t 30 -P 4
# then against BBR
sysctl -w net.ipv4.tcp_congestion_control=bbr
iperf3 -c REMOTE_IP -t 30 -P 4

In a typical test on a 1 Gbps VPS with an overseas peer, expect something like:

AlgorithmThroughput (4 streams)Retransmits
CUBIC340-420 Mbps2.1%
BBR780-920 Mbps3.4%

The throughput gain of 2-3x on lossy or high-latency paths is typical; on a clean local link with zero loss, CUBIC and BBR are close, and the difference will be small. That is expected — BBR shines exactly where packet loss or bufferbloat exists, which is most real-world inter-provider traffic. If your test shows no improvement, your bottleneck is not congestion control, and you should look at CPU, disk, or the provider’s bandwidth cap instead.

Real-World Workloads That Benefit

The biggest wins show up in three places:

  • Large file transfers — backups, database dumps, media delivery. A backup job that took 40 minutes under CUBIC often completes in 15-20 minutes with BBR on the same pipe.
  • Cross-continental traffic — any route with high latency and occasional loss. BBR’s pacing keeps the window full despite the RTT.
  • Busy uplinks — a VPS sharing a provider uplink with noisy neighbors sees far less throughput collapse, because BBR does not halve the rate on every drop.

Workloads that see little benefit: localhost traffic (no network path to optimize), single-stream tests below the bottleneck (BBR adds nothing if CUBIC already saturates), and CPU-bound transfers where the application cannot generate enough data to fill the pipe. Enable BBR and then decide with numbers — if your iperf3 result is flat, keep it anyway, because it costs nothing and helps the bursty moments.

Interaction with Other Network Settings

BBR works alongside, not instead of, the rest of your network tuning. Raise the socket buffers so the larger windows BBR opens are actually usable:

sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
sysctl -w net.ipv4.tcp_slow_start_after_idle=0

tcp_slow_start_after_idle=0 stops the congestion window from collapsing when a connection goes idle, which matters for APIs with frequent short bursts. Do not combine BBR with aggressive tcp_congestion_control hacks like setting it per-route unless you have a specific reason; the global setting covers new connections and is what most guides — including the ones you will find in the FAQ on our main site — recommend. Also note that BBR is a sender-side algorithm: both endpoints do not need it, only the side that sends the bulk data does. Enabling it on your VPS helps outbound transfers (backups, media, API responses) immediately, even if the client runs CUBIC.

Rolling Back Is One Command

If you ever see a regression, reverting is trivial:

sysctl -w net.ipv4.tcp_congestion_control=cubic
rm /etc/sysctl.d/99-bbr.conf /etc/modules-load.d/bbr.conf
sysctl --system

There is no persistent state to clean up; the algorithm is selected per new connection at the kernel level. In my experience across dozens of VPS setups, the only reason to revert is a specific workload that measurably regresses — and the iperf3 comparison above will tell you that within ten minutes.

Summary

  • BBR requires kernel 4.9+; check with modinfo tcp_bbr.
  • Enable with net.ipv4.tcp_congestion_control=bbr plus net.core.default_qdisc=fq.
  • Persist via /etc/sysctl.d/99-bbr.conf and a modules-load entry.
  • Verify with sysctl and ss -Tin; quantify with iperf3 against a second server.
  • Expect 2-3x throughput on lossy or long-distance paths, and no change on clean local links.

TCP BBR is one of the few kernel changes that delivers a measurable, immediate speedup for outbound transfers on a VPS, with essentially zero downside and a one-command rollback. Enable it, measure it, and keep it — your backup windows and media transfers will thank you. For guidance on choosing a VPS plan with the bandwidth and network quality to match your transfer volumes, see the provider comparison table and features overview on our main site.

Leave a Reply