protonscr

Transfer speed between two high performance PC limited around 140 Mbps

steamopen Steam client
ValveSoftware/steam-for-linux#9364 · opened 2023-04-25 by NTMan · updated 2026-08-25 · 16 comments · github
NNTMan 2023-04-25 github

Your system information

  • Steam client version (build number or date): 1681864962
  • Distribution (e.g. Ubuntu): Fedora Rawhide
  • Opted into Steam client beta?: Yes
  • Have you checked for system updates?: Yes
  • Link to full system information report as gist

Please describe your issue in as much detail as possible:

Screenshot from 2023-04-25 13-53-00

Transfer speed between two PC limited around 140 Mbps
But network interfaces and storage system allow transfer games much faster.
For example when I receive games from valve servers download speed reach 900Mbps.

Steps for reproducing this issue:

  1. Download the game to one computer
  2. Download same game on other computer in local network with high performance network and storage.
MMagmaiKH 2023-10-23 github

Is this a Linux client issue?
My PC is a beast, 10G NIC (get 10G between it and my server), storage is not merely an M.2 but is the SK Hynix P41. (It's faster than 10Gbps.)
It transfers at ~60Mbps from the Linux client to a Windows client.

Aacuteaura 2024-02-17 github

I am seeing this only when the client is on WiFi, though the WiFi isn't the limiting factor (It's a U7 Pro), since downloads directly from a CDN are 4-5 times as fast on WiFi and the client hosting the network transfer is wired (even to the same switch as the AP)

The same client with a 2.5 GbE USB adapter pulls 1.2 Gbps (also not more, even though both computers are now on one switch, one with 10 GbE and one with 2.5 GbE).

RRodoMa92 2024-03-17 github

Same behavior on my end, and from the peer statistics it seems to be limited to one single thread. I can get 6 times the performance by downloading it directly from Steam's server, which completely defeats the point of the feature IMO.

Aarazilsongweaver 2024-03-21 github
Aacuteaura 2024-03-22 github

This issue is just about local transfers, you're looking for #10248

TTomyLobo 2025-01-18 github

same issue here.
130 Mbps with Steam
Ended up rsyncing the game to the other machine, at 500 Mbps

Xxamindar 2025-05-06 github

Sad to see such an old issue still open. Same issue here of course. Transfers between desktop, or laptop, or steam deck all much slower than just downloading from Valve. I have disabled this feature on all my machines because of how much slower it is over local connections.

PPipodi 2025-05-26 github

Adding this information as I've opened this, using scp to/from Steam Deck to/from high end PC gets full bandwidth.

CColorblindMonk 2025-09-01 github

I've also been experiencing this issue for a long time. If my Linux machine is pushing a local transfer to a Windows machine and they're wired up to the same switch or router, it will push the data as fast as it can. However, when I moved that same Windows machine to another room and connected it to a 2.5G MoCA adapter (ethernet over coax), speeds dropped to 140-180Mbps. It's also the exact same behavior with my handheld devices connected over Wi-Fi. Over the same types of connections, if my Windows machine was the local transfer host, there are no issues.

The Linux Steam client seems to be very finicky about your network when acting as the host for local transfers. Anything less than a direct wired connection just doesn't want to work.

Eeathtespagheti 2025-12-03 github

Same issue here, steam deck over 5GHz WiFi and Desktop PC (Arch Linux) wired with 2.5Gbps ethernet, I get about 150mbps when using local transfer, and 600mbps via WiFi from steam servers

IIlliux 2026-06-20 github

I was investigating this myself and @ColorblindMonk gave me the clue I needed (thanks!). I also was trying to transfer over MoCA with a Linux machine as receiver.

It looks like what's happening is Steam must be disabling socket auto-tuning.

$ ss -tinm dst 192.168.8.220 State Recv-Q Send-Q Local Address:Port Peer Address:Port ESTAB 0 0 192.168.8.224:40065 192.168.8.220:27040 skmem:(r0,rb262144,t0,tb4608,f0,w0,o0,bl0,d44) cubic wscale:8,2 rto:205 rtt:4.119/0.239 ato:40 mss:1448 pmtu:1500 rcvmss:1448 advmss:1448 cwnd:13 bytes_sent:2574432 bytes_retrans:2576 bytes_acked:2571857 bytes_received:15747648882 segs_out:890609 segs_in:10887414 data_segs_out:21767 data_segs_in:10885251 send 36560330bps lastsnd:9 pacing_rate 73107344bps delivery_rate 16956328bps delivered:21768 app_limited busy:32242ms sndbuf_limited:19994ms(62.0%) retrans:0/17 dsack_dups:17 rcv_rtt:4 rcv_space:202720 rcv_ssthresh:174080 minrtt:3.407 rcv_ooopack:75 snd_wnd:64768 rcv_wnd:174080

if I look at my settings....

$ sysctl net.ipv4.tcp_moderate_rcvbuf net.ipv4.tcp_rmem net.core.rmem_default net.core.rmem_max net.ipv4.tcp_moderate_rcvbuf = 1 net.ipv4.tcp_rmem = 4096 131072 33554432 net.core.rmem_default = 212992 net.core.rmem_max = 4194304

rb262144 = receive buffer of exactly 256KiB which is exactly twice the 128KiB default. Linux allocates, as far as I've been able to tell, twice the application requested buffer. So this means that steam for some reason has the connection set to lock at the default receive buffer and disable autotuning.

That produces exactly the behavior @ColorblindMonk saw. Because MoCA has great bandwidth but much higher latency (which you can see above in my rtt:4.119/0.239). So what happens is on high latency connections the TCP throughput becomes limited by the combination of RTT times and small receive buffer.

IIlliux 2026-06-20 github

I did a bpftrace to capture __sys_setsockopt after changing my defaults just to differentiate things. Then started steam, waited for the transfer to start, and closed it:

Attached 1 probe
pactl            pid=45833   fd=14   opt=8   value=65472
IPC:CSteamEngin  pid=45742   fd=117  opt=8   value=131072
pactl            pid=45842   fd=14   opt=8   value=65472
pactl            pid=45848   fd=14   opt=8   value=65472
pactl            pid=45856   fd=14   opt=8   value=65472
IOCP Thread 0    pid=45742   fd=44   opt=8   value=131072
IOCP Thread 0    pid=45742   fd=124  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=135  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=138  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=136  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=140  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=139  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=145  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=168  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=170  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=172  opt=8   value=131072
IPC:CSteamEngin  pid=45742   fd=173  opt=8   value=131072

So steam is calling SO_RCVBUF=131072 even if the system default is different, which disables auto-tuning.

IIlliux 2026-06-20 github

Just to be absolutely sure, I correlated bpftrace and ss on a fresh run:

State                             Recv-Q                             Send-Q                                                         Local Address:Port                                                           Peer Address:Port                             Process                                                        
ESTAB                             0                                  0                                                              192.168.8.224:57297                                                         192.168.8.220:27040                             users:(("steam",pid=54431,fd=175))                            
	 skmem:(r0,rb262144,t0,tb4608,f0,w0,o0,bl0,d0) cubic wscale:8,2 rto:205 rtt:4.089/0.257 ato:40 mss:1448 pmtu:1500 rcvmss:1448 advmss:1448 cwnd:10 bytes_sent:121688 bytes_retrans:56 bytes_acked:121633 bytes_received:469389652 segs_out:27341 segs_in:325285 data_segs_out:1058 data_segs_in:325097 send 28329665bps lastsnd:50 lastrcv:1 lastack:1 pacing_rate 56647208bps delivery_rate 15938352bps delivered:1059 app_limited busy:1896ms sndbuf_limited:813ms(42.9%) retrans:0/1 dsack_dups:1 rcv_rtt:3.125 rcv_space:182448 rcv_ssthresh:162400 minrtt:3.377 snd_wnd:64256 rcv_wnd:162400
IPC:CSteamEngin  pid=54431   fd=175  opt=8   value=131072

Showing the setsockopt call for SO_RCVBUF=131072 on the exact fd (175) used for the local transfer.

Also if we use my numbers above, rcv_wnd: 162400 bytes & rtt: 4 ms = 40,600,000 bytes/s ceiling. So ~38.7MiB/s which is what I observed in Steam in my case.

IIlliux 2026-06-20 github

And just as a final confirmation I used a small program to set SO_RCVBUF and TCP_WINDOW_CLAMP on Steam's local transfer socket while it was in progress, and my transfer speed immediately increased.

Llonsdaleite 2026-08-04 github

I tracked this down to Steam explicitly calling:

setsockopt(fd, SOL_SOCKET, SO_RCVBUF, 131072, ...)

on its download sockets.

On Linux, explicitly setting SO_RCVBUF disables receive-buffer autotuning for that socket. It also results in a small TCP window scale being negotiated, so the advertised receive window cannot grow enough for high-bandwidth links with even moderate RTT. This appears to affect both Game Transfer over LAN and regular CDN downloads.

I made a small open-source workaround for SteamOS:

https://github.com/lonsdaleite/steam-download-uncap

It uses an LD_PRELOAD interposer that ignores only SO_RCVBUF calls while reporting success to Steam, leaving the Linux kernel free to autotune the receive buffer.

Measured with a 2.5 GbE PC sending to a Wi-Fi 6E handheld:

  • Before: 65 MB/s
  • After: 160 MB/s
  • scp over the same path: 175 MB/s

Socket state before:

rb: 262144
rcv_wnd: 171536
rcv_wscale: 2

After:

rb: 33554432
rcv_wnd: 22671360
rcv_wscale: 10

Neither CPU, storage nor the wireless link was saturated at 65 MB/s. Before applying the workaround, starting a second stream in parallel raised aggregate throughput to 141 MB/s, further indicating a per-connection receive-window limit.

The workaround is entirely user-level, reversible, requires no sudo and does not modify the SteamOS root filesystem. Source code and installation/uninstallation instructions are in the repository.

The preferable upstream fix would be for the Steam client not to set SO_RCVBUF on Linux download sockets and to leave receive-buffer sizing to kernel autotuning.

Ggehhilfe 2026-08-25 github

I have comparable problem when streaming with high quality. Key frames will overflow the buffer and quality degrades. Report generated with AI. Maybe it helps for now i will also use LD interposer

Steam Remote Play: hardcoded UDP socket buffers overflow on keyframe bursts (send side on Linux host, receive side on macOS client)

Summary: Steam Remote Play sets small, fixed SO_SNDBUF/SO_RCVBUF values that
override the OS defaults and are too small to absorb high-bitrate 4K keyframe
bursts. Both the host send path and the client receive path drop packets on IDR
frames. FEC cannot recover the resulting correlated burst loss, so the picture
degrades badly while the reported per-second loss stays deceptively low.

Environment

  • Host (encoder): CachyOS Linux, wired gigabit, RX 9060 XT, VAAPI hardware H.264.
    Steam Version: 1785799196

  • Client (decoder): macOS [version], MacBook Pro, Metal decode, wired gigabit via USB-C Ethernet.
    Steam Version: 1785799196

  • Stream: 1440p–4K, 60–144 FPS, H.264, on an otherwise idle LAN.

Symptom

Persistent quality degradation. In-stream overlay showed ~10% frame loss and the
client reported ~3 lost packets/sec — but actual raw packet loss was far higher;
the low reported number was the residual after FEC.

Network ruled out

  • iperf3 UDP host→client: 0% loss at 300 Mbit/s steady; 0% at 50 Mbit/s in
    300-packet bursts; 0.014% at 500 Mbit/s bursts. Ping 0.7 ms.
  • So the wire and both NICs are clean; the loss is at the socket layer.

Root cause — socket buffers overflow on keyframe bursts

Host send side: Steam sets SO_SNDBUF to 512 KB. On 4K keyframe bursts this
overflows; kernel send-buffer error counters climbed. Raising it to 8 MB stopped
the host-side drops.

Client receive side (macOS): Steam pins SO_RCVBUF to 262144 (256 KB) via
setsockopt, which overrides net.inet.udp.recvspace (so tuning the sysctl has
no effect). During streaming, netstat -s -p udp "dropped due to full socket
buffers" climbed at ~500 packets/sec. Raising net.inet.udp.recvspace/
kern.ipc.maxsockbuf did nothing, because Steam overrides the default.

Proof

Forcing the live client socket's SO_RCVBUF from 256 KB to 4 MB
(same socket, mid-stream):

  • rhiwat: 262144 → 4194304
  • "dropped due to full socket buffers": ~500/sec → 0/sec (flat for the whole
    measurement window)
  • Recv-Q settled around ~7.6 KB (buffer absorbing bursts instead of overflowing)
  • Picture quality cleared immediately.

Why 256 KB / 512 KB is too small

A 4K IDR keyframe is hundreds of KB to a few MB and arrives as a line-rate burst.
256 KB holds only ~14 ms of data at 150 Mbit/s, so the tail of each keyframe
overflows before the decode thread reads once. This is correlated burst loss,
which FEC recovers poorly — hence bad video despite low reported loss.

Requested fix

Size SO_SNDBUF/SO_RCVBUF as a function of the negotiated bitrate/resolution
(e.g. enough to hold the largest expected keyframe plus a few frame intervals),
or stop overriding the OS socket-buffer defaults, or expose the buffer
size as a user setting. The current fixed constants don't scale to the 4K/high-FPS
modes Steam now supports.