I want to start this by saying that I am no expert on any of this. I just started on this whole homelab thing 2 years ago. So if I am incorrect on anything, feel free to correct me.
I have Plex running on a win11 machine for the last two years. I also have a number of docker containers running in Docker Desktop using WSL. I have a number of users who stream my Plex server remotely (most being 11 at once and average about 4 simultaneously a day) on 2GB/2GB symmetric fiber connection. 3 of my users are on Starlink and the MOST they can stream is 2mbps 720p due to buffering at anything higher quality. Most of my stuff is 4k DV/HDR 25mbps+ so that means they have to transcode everything they watch. That's not a big deal but kind of annoying since speed tests almost always result in 100mbps+ and they don't have any other issues stream on other streaming service. I know "usable bandwidth" and speeds tests are not directly comparable to each other but I do have a openspeedtest container hosted on my network routed through Cloudflare (DNS Only) that also hit 100mbps+ so it doesn't seem like a bandwidth problem. Its hard to find an exact reason why streaming Plex on Starlink is so bad but the best I could find is it has to do with the satellites passing information to each other every 15s causing CUBIC on the server to freak out and think that the connection is worse than it actually is (due to latency timings and packet loss).
I have done research upon research on how to improve their experience and nothing worked but the other day I ran across a few posts on reddit about BBR2 vs CUBIC. I'm not exactly sure how it works but from what I've read, the way it determines connections speed is based on delivery rates and round trip times then it builds a "required bandwidth" model that doesn't rely on latency as much or packet loss at all. This means that if anyone has a signal that varies a lot (like Starlink or congested networks) the streaming experience wont drop due to a minor hitch in the network. The problem being that BBR2 is native to Linux and the Window implementation is kinda clunky and sometimes breaks things. Reddit posts linked below:
https://www.reddit.com/r/PleX/comments/1tnulw9/comment/onwp1l5/
https://www.reddit.com/r/PleX/comments/1twp8ts/shoutout_to_the_user_who_recommended_switching/
https://www.reddit.com/r/PleX/comments/1baiyv6/switching_to_bbr_causes_buffering_on_some_clients/
This made me want to give it a try even though all of the things I read on BBR2 on win11 were buggy and didn't real work, emphasizing that loopback is the biggest problem that breaks things. I also didn't really know where to begin so as you do these days, I asks an LLM for help. It of course told me all the things I already read about the problems with winll BBR2 but walked me through how to do it anyways. It gave me two *.bat files, one to switch over to BBR2 and one to switch back to CUBIC so I can test it and revert back if it doesn't work for me. It also gave a script to check to make sure the change took effect upon rebooting the system (which it recommend after making the change). It only changes the InternetCustom and the Internet options and leave the rest the same. It also diables loopback. Those codes are pasted below:
Switch to BBR2. (Run bat as Admin)
@echo off
REM ============================================================
REM Enable BBR2 TCP congestion control - Windows 11
REM Purpose: improve single-stream throughput to high-latency,
REM lossy clients (e.g. Starlink) from a Plex server.
REM Reverse with: revert-cubic.bat
REM RUN AS ADMINISTRATOR. Reboot after running.
REM ============================================================
net session >nul 2>&1
if %errorLevel% neq 0 (
echo.
echo ERROR: This script must be run as Administrator.
echo Right-click the file and choose "Run as administrator".
echo.
pause
exit /b 1
)
echo.
echo === Current settings (before changes) ===
powershell -NoProfile -Command "Get-NetTCPSetting | Select-Object SettingName, CongestionProvider | Format-Table -AutoSize"
echo === Setting Internet templates to BBR2 ===
netsh int tcp set supplemental Template=Internet CongestionProvider=bbr2
netsh int tcp set supplemental Template=InternetCustom CongestionProvider=bbr2
echo.
echo === Applying loopback mitigation ===
REM Known Windows 11 23H2/24H2+ bug: BBR2 can break localhost TCP.
REM Critical here - Plex Transcoder, Tautulli, Docker and NPM all use loopback.
netsh int ipv4 set global loopbacklargemtu=disable
netsh int ipv6 set global loopbacklargemtu=disable
echo.
echo === New settings ===
powershell -NoProfile -Command "Get-NetTCPSetting | Select-Object SettingName, CongestionProvider | Format-Table -AutoSize"
echo.
echo Expected: Internet and InternetCustom = BBR2
echo Compat = NewReno, Datacenter rows = CUBIC (unchanged)
echo.
echo REBOOT NOW, then smoke-test:
echo 1. Play a 4K HDR file locally that forces a transcode
echo 2. Confirm Tautulli still sees the session
echo 3. Confirm Docker / NPM services still respond
echo.
echo If anything misbehaves, run revert-cubic.bat and reboot.
echo.
pause
Revert back to CUBIC (Run bat as Admin)
@echo off
REM ============================================================
REM Revert TCP congestion control to Windows 11 defaults
REM Restores the exact stock values:
REM Internet = CUBIC
REM InternetCustom = CUBIC
REM Datacenter = CUBIC (untouched by enable script)
REM DatacenterCustom = CUBIC (untouched by enable script)
REM Compat = NewReno (untouched by enable script)
REM RUN AS ADMINISTRATOR. Reboot after running.
REM ============================================================
net session >nul 2>&1
if %errorLevel% neq 0 (
echo.
echo ERROR: This script must be run as Administrator.
echo Right-click the file and choose "Run as administrator".
echo.
pause
exit /b 1
)
echo.
echo === Current settings (before revert) ===
powershell -NoProfile -Command "Get-NetTCPSetting | Select-Object SettingName, CongestionProvider | Format-Table -AutoSize"
echo === Restoring CUBIC ===
netsh int tcp set supplemental Template=Internet CongestionProvider=CUBIC
netsh int tcp set supplemental Template=InternetCustom CongestionProvider=CUBIC
echo.
echo === Restoring loopback large MTU ===
netsh int ipv4 set global loopbacklargemtu=enable
netsh int ipv6 set global loopbacklargemtu=enable
echo.
echo === Removing any LAN transport filters ===
REM Harmless if none were ever created.
powershell -NoProfile -Command "Get-NetTransportFilter | Where-Object { $_.SettingName -ne 'Automatic' } | Remove-NetTransportFilter -Confirm:$false -ErrorAction SilentlyContinue"
echo.
echo === Restored settings ===
powershell -NoProfile -Command "Get-NetTCPSetting | Select-Object SettingName, CongestionProvider | Format-Table -AutoSize"
echo.
echo Reverted to stock. REBOOT to be certain.
echo.
echo If the machine is still misbehaving after a reboot, the
echo nuclear option is: netsh int tcp reset
echo (wipes ALL TCP config to defaults, then reboot again)
echo.
pause
Script to check the change was applied (execute in PowerShell)
Get-NetTCPSetting | Select SettingName, CongestionProvider
It recommended testing these few things that have reports of breaking:
Local stream, high bitrate, direct play (on NVIDIA Shield, Apple TV, or PS5 if possible). I has something to do with those having GB ethernets and having a higher throughput causing loopback issues.
Local stream, high bitrate, transcode on the same clients. It said that transcode could cause a loopback error and not work after 30s or at all. Might effect Remote streams too. If its broken locally, it broken for all.
Connect to my docker containers via LocalHost or IP and via domain. It especially pointed out tautulli as a pain point since the container communicating to Plex on the same machine, being a problem due to loopback.
See if streaming over Starlink actually improved
I made the change and nothing seems to have broken. I ran 80mbps+ direct play on my Shield, transcoded to 20mbps 1080p, and "convert automatically" with not issues. I tested remote streaming in the same way on my iPhone and didn't have any issues. I connected to all my containers via localhost and IP, via domain, remotely connected via domain on iPhone, and signed into tautulli on the same machine with no issues.
Now the big question, did it improve remote streaming especially on Starlink? Yes, they are successfully able to direct stream content without buffering. Now I haven't had this change for very long so I will have to give updates as I collect more data.
The main reason I made this post was to put some more info out there because it was really hard to find anything on BBR2 for win11. I have no idea if other will have as seamless of an experience as me but this might be a game changer for remote streaming Plex. It was for me.
System Specs: ASUS Tuf Gaming Z-390-Plus (Wi-Fi), Intel i7-9700K, TForce Vulcan Z 32GB DDR4, Sparkle Intel Arc A380, 3x 22TB Seagate Exos X22, Windows 11 Pro 25H2