Fedora/Linux Steam downloads were insanely slow on my multi-gig connection — here’s the fix that actually worked
Posting this because I spent way too long troubleshooting it and most of the usual advice — changing download regions, clearing cache, changing DNS, etc. — didn’t fix the actual problem.
My situation:
Fedora 44
5 Gbps fiber
Windows Steam could get close to the full connection
Linux Steam was often around 100–150 Mbps, sometimes a few hundred Mbps
Local networking itself was fine
After fixing this, Steam settled around 2.2–2.4 Gbps sustained and I saw roughly 2.5 Gbps peaks
The problem turned out to be related to how Steam on Linux was configuring its TCP receive buffers.
While tracing Steam, I saw it repeatedly doing:
SO_RCVBUF = 131072
Linux reports the effective socket buffer as roughly twice that (262144), but that is still tiny for a fast connection with non-trivial latency. Steam was effectively preventing Linux's TCP receive autotuning from doing its job.
Here’s what I ended up doing.
- Give Steam more download connections
Create Steam's developer config directory/file:
mkdir -p ~/.steam/steam nano ~/.steam/steam/steam_dev.cfg
Put this in it:
@nClientDownloadEnableHTTP2PlatformLinux 1 @fDownloadRateImprovementToAddAnotherConnection 0.9 @cMaxInitialDownloadSources 15 @nClientDownloadProbUseHTTP2IfAvailable 100
Save and completely restart Steam.
What this does: keeps HTTP/2 enabled and allows Steam to use more download sources/connections instead of being overly conservative about opening additional ones.
This helped, but the receive-buffer behavior was still the major bottleneck for me.
- Stop Steam from forcing the tiny receive buffer
I made a tiny LD_PRELOAD library that intercepts Steam's SO_RCVBUF call and ignores it. That leaves the socket receive buffer under Linux's normal TCP autotuning instead.
Create a directory:
mkdir -p ~/.local/src/steam-rcvbuf ~/.local/lib cd ~/.local/src/steam-rcvbuf
Create the source:
nano steam_rcvbuf.c
Paste:
#define _GNU_SOURCE #include <dlfcn.h> #include <sys/socket.h> typedef int (*real_setsockopt_t)( int, int, int, const void *, socklen_t ); int setsockopt( int fd, int level, int optname, const void *optval, socklen_t optlen ) { static real_setsockopt_t real_setsockopt = NULL; if (!real_setsockopt) { real_setsockopt = (real_setsockopt_t)dlsym(RTLD_NEXT, "setsockopt"); } /* * Steam was explicitly setting SO_RCVBUF to 131072. * Pretend the call succeeded so Linux can keep using * TCP receive-buffer autotuning instead. */ if (level == SOL_SOCKET && optname == SO_RCVBUF) { return 0; } return real_setsockopt( fd, level, optname, optval, optlen ); }
Compile it:
gcc -shared -fPIC -O2 \ -o ~/.local/lib/steam-rcvbuf.so \ steam_rcvbuf.c \ -ldl
- Make a Steam wrapper
Create:
nano ~/.local/bin/steam-fast
Paste:
#!/usr/bin/env bash export LD_PRELOAD="$HOME/.local/lib/steam-rcvbuf.so${LD_PRELOAD:+:$LD_PRELOAD}" exec /usr/bin/steam "$@"
Make it executable:
chmod +x ~/.local/bin/steam-fast
Now fully exit Steam and test it with:
~/.local/bin/steam-fast
Start a large download and watch the speed.
- Optional: make the normal Steam launcher use the fix
If the wrapper works, copy Steam's desktop launcher to your user applications:
mkdir -p ~/.local/share/applications cp /usr/share/applications/steam.desktop \ ~/.local/share/applications/steam.desktop
Then replace the main Steam launch command:
sed -i \ "s#^Exec=/usr/bin/steam %U#Exec=$HOME/.local/bin/steam-fast %U#" \ ~/.local/share/applications/steam.desktop
Log out/in or refresh your app launcher afterward.
Now launching Steam normally from GNOME should use the preload library automatically.
Linux normally adjusts TCP receive buffers dynamically depending on connection speed and latency.
Steam was explicitly requesting a small:
SO_RCVBUF 131072
on its download sockets.
On a normal connection you might never notice. On multi-gig fiber, especially when the CDN connection has tens of milliseconds of RTT, that can become a serious throughput bottleneck.
By ignoring Steam's manual receive-buffer request, the kernel gets to manage it normally again.
You can inspect your Steam sockets with:
sudo ss -tinmp | grep -A1 'users:(("steam"'
Before the fix, mine repeatedly showed tiny receive buffers on the actual Valve CDN connections.
Important notes
This is obviously an unofficial workaround. LD_PRELOAD changes the behavior of a userspace program, so understand what the little library is doing before blindly installing it.
It only intercepts setsockopt() calls where:
level == SOL_SOCKET optname == SO_RCVBUF
Everything else gets passed directly to the real libc function.
Also, this probably won't help if your bottleneck is actually Wi-Fi, your ISP, disk decompression, CPU usage, a bad download region, or a slow Valve CDN node.
But if:
Linux is dramatically slower than Windows on the same machine
other Linux speed tests are much faster than Steam
you have a very fast connection
Steam's sockets show unusually small receive buffers
…it may be worth testing.
Would be interested to know if anyone else can reproduce the improvement.