How to reserve bandwidth for Stadia in your home network - MacGyver style

12 March 2021

Why, tho?

Stadia has been my main gaming platform for a few months now and I've clocked about 200 hours without any issues whatsoever. On 5GHz WiFi even.

Me and my wife usually play games together, but not every game interests her in the same way, which means she sometimes does her own surfing and streaming while I play and, depending on what she's doing, that can cause my stream to hiccup every once in a while. Not really a big deal, but it can be annoying, depending on what's going on.

I'm using a Fritz!Box 7530 and I've set up different SSIDs for 2.4 GHz and 5 GHz WiFi. Every device, except for the Chromecast with Google TV and the Stadia controller, uses the 2.4 GHz WiFi. That ensures that the 5 GHz network is kept clean for maximum performance and this way I can make sure that the Chromecast will always use 5 GHz without being dropped to 2.4 GHz. Our other devices wouldn't benefit from 5 GHz wifi anyway and in their case the longer range of 2.4 GHz is highly appreciated.

I've explored several ideas to limit the bandwidth on the 2.4 GHz network, but the basic QoS settings of my router simply do not offer such a feature. The higher tiered 7590 has an option to "reserve bandwidth for your home network" when setting up guest WiFi, but I don't have one of those and even if I did there would be no way to automate it. Also the guest WiFi always uses 2.4 GHz and 5 GHz with no way of splitting them. Maybe not a big deal if you don't use WiFi for cloud gaming, but something to keep in mind.

OpenWrt Logo
OpenWrt Logo

The solution: OpenWrt

Then I remembered reading about custom OS' for routers called OpenWrt (or the alternative dd-wrt) and, lo and behold, there is an official build for an old and unused TP-Link WiFi Repeater I had lying around. The bad news is, that the device is extremely low spec and outdated and while you can flash and boot the latest version, all the settings will be wiped upon reboot, since there is no space left to actually store them. A fate which a lot of similar devices share. One possible workaround would be to look for an older and working version or buy a more recent and better supported device, but I wanted the best I could get with the device I had and I was prepared to let go of a graphical user interface if need be, since I'm quite comfortable with CLIs.

How I set it up

I will now explain how I set up my device, but this is by no means a comprehensive tutorial. My solution is very specific to how my home network is set up and how all my devices connect to it. With this blog post I want to give you a small headstart on tackling your own problem. This is easily adaptable and can be used for more than to Stadia or other cloud gaming services.
If you're lucky you may find a fully featured and ready to flash build of OpenWrt for your specific router or repeater. In that case setting it up will probably be as easy as reading a few simple guides and using the graphical user interface of OpenWrt through a web browser, just like you would setup and configure an OEM router.
If you're unlucky, like me, you will have to have basic knowledge of using a UNIX command line and know how to solve problems by doing extensive research. Maybe you will even have to compile or build the OS yourself.
Or just throw money at the problem. That always works, too.

It took me a few hours of research and trial and error, but I finally created my own build where I had every module I needed while still having enough space left to store settings and scripts. It's not quite bleeding edge, but it's at least as up to date as the latest official release for that device. Compiling from the latest source did work, but even with all the changes I made, the filesize was way to big. I didn't bother with compilation much longer, as it takes quite some time and would add up quickly. I instead settled for the imagebuilder, where I could create different builds in a matter of seconds. With a bit more patience, knowledge and skill, maybe even the latest version from source would have been possible, but for me it wasn't worth the extra time and effort.

My build doesn't offer a GUI anymore, nor does it have IPv6 support, ppp, or a firewall, all things which aren't needed in my case, since the router takes care of them already. I also dropped USB support (it doesn't even have a port), and added support for WPA encryption, a built-in webserver with support for LUA scripting (which will come in handy later) and, most importantly, an SQM (smart queue management) module, which I could abuse to get what I set out to achieve.

I then set it up as a "dumb access point" and used the same SSID and password of my 2.4 GHz network for a seamless transition. On the router I disabled the 2.4 GHz network, but left the 5 GHz one enabled.

After getting basic access point functionality I went on to configure the SQM module. It was really straightforward. I just had to change a few values in a single config file and restart the service.

SQM config
SQM config

It worked brilliantly! I configured it to limit the bandwidth to 16 Mbit/s down and 4 Mbit/s up. The rest would be reserved for 5 GHz WiFi and other ethernet ports of my router.

But we're not quite there, yet. I didn't want to manually toggle it on and off, nor did I want to leave it on all the time, so I needed something to do that for me.

As stated before, I added a tiny webserver (uhttpd) and a LUA extension, which enabled me to use two URLs (e.g. /lua/sqm-on and /lua/sqm-off) to start and stop the SQM module:

function handle_request(env)
    uhttpd.send("Status: 200 OK\r\n")
    uhttpd.send("Content-Type: text/html\r\n\r\n")
    if env.REQUEST_URI == "/lua/sqm-on" then
        io.popen("/etc/init.d/sqm start")
        uhttpd.send("SQM ON")
    elseif env.REQUEST_URI == "/lua/sqm-off" then
        io.popen("/etc/init.d/sqm stop")
        uhttpd.send("SQM OFF")
    else
        uhttpd.send("Hello World")
    end
end

On the Chromecast with Google TV I installed Automagic* and set it up to make a simple HTTP request to the respective URL when launching or closing the Stadia app and added a small toast notification to top it off. The last thing to do was to disable the SQM autostart and I was done.

(* Sadly, Automagic is not supported anymore. Because of that it's now completely free and still works great, but if you don't like it, there are a lot of alternative apps with similar capabilities for you to choose from.)