http2: increase default window sizes#64623
Conversation
|
Review requested:
|
| // to window_size / RTT. With a 32MB connection window, throughput is | ||
| // significantly improved. See https://github.com/nodejs/node/issues/38426 | ||
| CHECK_EQ(nghttp2_session_set_local_window_size( | ||
| session, NGHTTP2_FLAG_NONE, 0, 33554432), 0); |
There was a problem hiding this comment.
There's a pre-existing issue that this exposes: you can't configure this in advance. You can only control the connection window with session.setLocalWindowSize once you have a session, but at that point this initial WINDOW_UPDATE has already been sent, and shrinking the window isn't effective as shown in the tests here (it just blocks further updates, it can't reduce what's already been sent). The stream window is configurable in advance (it's a SETTINGS parameter) but this connection window isn't.
That already existed implicitly but it was kind of OK when the initial window was small, but it's a real problem with a very large initial window I think, since there's basically no way to override this to make it any smaller again if you need to.
Can we add client & server options for this, so it can be configured before the first WINDOW_UPDATE is sent somehow?
| // to window_size / RTT. With a 32MB connection window, throughput is | ||
| // significantly improved. See https://github.com/nodejs/node/issues/38426 | ||
| CHECK_EQ(nghttp2_session_set_local_window_size( | ||
| session, NGHTTP2_FLAG_NONE, 0, 33554432), 0); |
There was a problem hiding this comment.
Nit: would be nicer to extract this as a constant
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #64623 +/- ##
==========================================
- Coverage 90.23% 90.14% -0.10%
==========================================
Files 741 743 +2
Lines 241681 242321 +640
Branches 45547 45626 +79
==========================================
+ Hits 218075 218434 +359
- Misses 15141 15369 +228
- Partials 8465 8518 +53
🚀 New features to boost your workflow:
|
5c9bc03 to
4351b51
Compare
|
Both addressed:
|
4351b51 to
31761a0
Compare
RafaelGSS
left a comment
There was a problem hiding this comment.
Wouldn't it be
semver-major
|
yes |
70882db to
bd4cbd3
Compare
I do think this would be useful, but doesn't need to block this - I'll open a separate PR. |
bd4cbd3 to
86b969b
Compare
Increase the default HTTP/2 stream window from 64KB (65535) to 4MB (4194304) and the default local connection window to 32MB (33554432). The default 64KB window limits throughput on high-latency connections to window_size / RTT. With a 250ms RTT, throughput is limited to 256KB/s. The new defaults improve throughput to 16MB/s (128Mbps) for the stream window and 128MB/s (1Gbps) for the connection window. Fixes: nodejs#38426 Signed-off-by: Matteo Collina <hello@matteocollina.com>
86b969b to
d0c68ba
Compare
Ethan-Arrowood
left a comment
There was a problem hiding this comment.
CI failure seems related to the change here; test-http2-respond-with-file-connection-abort is failing across multiple systems and that isn't a known flake. Leaving a request changes to this gets fixed before landing.
|
I was able to reproduce locally (5/12 runs of that test crashes with SIGSEGV). Assisted by Claude, the fix is possible a null-guard at |
|
I was a bit surprised by that flake coming out of a change like this, so I looked into it more - I think it is an existing clear bug, just made more visible by this change, but interestingly there's actually a reported issue (#56825) that seems to have the same or very similar crash in |
When a stream is destroyed while a synchronous write is in flight from StreamPipe::ProcessData, ReportWritesToJSStreamListener:: OnStreamAfterReqFinished can be called with a null stream_ or a null req_wrap, causing a null pointer dereference. This race becomes more likely with larger HTTP/2 windows (e.g., nodejs#38426) because more data is in flight during session teardown. Add early-return guards for both cases to prevent the crash. Refs: nodejs#38426 Refs: nodejs#56825 Signed-off-by: Matteo Collina <hello@matteocollina.com>
7b18703 to
16a74ad
Compare
|
I investigated the segfault in This is the same family of crash as #56825. Larger HTTP/2 windows make the race much more likely because more data is pipelined before session teardown completes. I added early-return null guards for both Also fixed Also fixed Fixes in commits: |
With the default window size increase, the server sends an additional WINDOW_UPDATE frame during session setup, increasing the frames received by the client from 7 to 8 on some platforms. Relax the assertion to check >= 7 instead of strict equality. Refs: nodejs#38426 Signed-off-by: Matteo Collina <hello@matteocollina.com>
When the writable sink is destroyed while there are still pending writes, WritableListener::OnStreamDestroy previously reset pending_writes_ to 0. This caused OnStreamAfterWrite to decrement the counter below 0, making the pending_writes_ == 0 completion check fail permanently — the oncomplete callback was never called, causing a timeout. Fix by: 1. Not resetting pending_writes_ in OnStreamDestroy — let OnStreamAfterWrite track completion naturally. 2. Using sink_destroyed_ flag in Unpipe to always remove the writable listener regardless of pending_writes_ count. 3. Using <= 0 (instead of == 0) when sink_destroyed_ is set, and guarding RemoveStreamListener against a null stream. This race became more likely with larger HTTP/2 windows (nodejs#38426) because more writes are in flight when session teardown begins. Refs: nodejs#38426 Refs: nodejs#56825 Signed-off-by: Matteo Collina <hello@matteocollina.com>
Signed-off-by: Matteo Collina <hello@matteocollina.com>
Increase the default HTTP/2 stream window from 64KB (65535) to 4MB
(4194304) and the default local connection window to 32MB (33554432).
The default 64KB window limits throughput on high-latency connections
to
window_size / RTT. With a 250ms RTT, throughput is limited to256KB/s. The new defaults improve throughput to 16MB/s (128Mbps)
for the stream window and 128MB/s (1Gbps) for the connection window.
Fixes #38426