feat(connlib): request larger buffers for UDP sockets - #8731
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
4a0a58a to
d92dc9c
Compare
d92dc9c to
d4bb883
Compare
0727312 to
4e4ac3f
Compare
|
Interesing, with this patch, Windows directly hands me a UDP socket with a 10MB buffer size without changing any system settings. This almost doubles the throughput I am getting during a download: Latest release: This PR: |
4e4ac3f to
eb352cf
Compare
8c49966 to
f1fb1ae
Compare
ecee85f to
f17df54
Compare
Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
180eb25 to
87a88e5
Compare
|
@jamilbk Did you see any throughput improvements with this PR? Because if not, then we don't need to bother increasing the buffer sizes on MacOS and can save ourselves the memory testing (although I think it would be good to confirm that it does in fact no affect user-space RAM usage). Edit: Built a new client here: https://github.com/firezone/firezone/actions/runs/14584121808/job/40906492534 |
|
This might explain the download / upload discrepancy: |
|
1 MB for 100 ms latency should still allow around 80 Mbps. I definitely don't see a +9 MB increase in userspace memory usage in the network extension process, so it's probably safe to say the buffer size only affects kernel memory (but on iOS, I'm not sure if that factors into our allowance even though it's kernel space). |
|
@thomaseizinger Thoughts on trying 8 MB for send and recv on Apple? |
|
What might be smart to do here is use much smaller buffers for the DNS queries since those don't need much bandwidth. The WireGuard socket will be the one where we need the 10 MB. |
You are welcome to experiment with it (it is just a small code change). As argued in the PR description, I think there are diminishing returns in increasing the send-buffer size. |
I'll push up another branch with a test. I disagree about the assumption that upstream is not as critical. For consumer use cases yes (browsing, streaming video) but I think in corporate settings the expectation is the speeds will roughly track line rate minus some overhead to be roughly in line with the vpn they were using before. Also the default iperf3 test many customers seem to be running defaults to testing upload :-/. |
We are disagreeing here on what we are debating. I am not saying upload is not critical. I am saying send buffer sizes are not as much of a critical component when it comes to achieving high throughput. The kernel will already flush out UDP packets as fast as it can from the buffer to the wire. Increasing this buffer size is not going to make that any faster. My understanding of how this works together is that we have back-pressure with extremely low latency to the producer and therefore don't need large buffers. The same is not true over the network. Receive buffers need to larger with increased latency because the remote needs to ackknowledge that it received a certain packet in order for backpressure to work. |
Moved the setting of increased buffers to a setter that we only call for the P2P sockets. |
I knew I was probably missing something, makes sense. |
Hm maybe, bear in mind the Gateway is on a burstable CPU so YMMV. I think it's probably safe to merge and at least rules one of the possible buffer size constraints out. |
Co-authored-by: Jamil <jamilbk@users.noreply.github.com> Signed-off-by: Thomas Eizinger <thomas@eizinger.io>




Sufficiently large receive buffers are important to sustain high-throughput as latency increases. If the receive buffer in the kernel is too small, packets need to be dropped on arrival.
Firefox uses 1MB in its QUIC stack 0.
quic-gorecommends to set send and receive buffers to 7.5 MB 1. Power users of Firezone are likely receiving a lot more traffic than the average Firefox user (especially with Internet Resource activated) so setting it to 10 MB seems reasonable. Sending packets is likely not as critical because we have back-pressure through our system such that we will stop reading IP packets when we cannot write to our UDP socket. The UDP socket is sitting in a separate thread and those threads are connected with dedicated queues which act as another buffer. However, as the data below shows, some systems have really small send buffers which are currently likely a speed bottleneck because we need to suspend writing so frequently.Assuming a 50ms latency, the bandwidth-delay product tells us that we can (in theory) saturate a 1.6 Gbps link with a 10MB receive buffer (assuming the OS also has large enough buffer sizes in its TCP or QUIC stack):
Experiments and research 2 show the following:
With the exception of Linux, the OSes appear to be quite generous with how big they allow receive buffers to be. On Linux, these limit can be changed by setting the
core.net.rmem_maxandcore.net.wmem_maxparameters usingsysctl.Most of our users are on Windows and MacOS, meaning they immediately benefit from this without having to change any system settings. Larger client-side UDP receive buffers are critical for any "download" scenario which is likely the majority of usecases that Firezone is used for.
On Windows, increasing this receive buffer almost doubles the throughput in an iperf3 download test.