Repository navigation
WebTransport: add anticipatedConcurrentIncomingUni/BidirectionalStreams support - #4011
Conversation
|
This PR is part of a stack of 3 bookmarks:
Created with jj-stack |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Closing sessions can still accept ineffective updates, and the public API does not document its 10,000-stream cap.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 2
Open (2)
What changed in this PR
Adds WebTransport APIs for configuring anticipated concurrent incoming streams and adjusts QUIC stream limits accordingly.
Changes:
- Tracks per-session anticipated unidirectional and bidirectional streams.
- Computes capped connection-wide limits with HTTP/3 control-stream overhead.
- Adds comprehensive stream-limit and lifecycle tests.
| File | Description |
|---|---|
neqo-http3/src/connection.rs |
Computes and applies connection-wide stream limits. |
neqo-http3/src/connection_client.rs |
Exposes public client configuration APIs. |
neqo-http3/src/features/extended_connect/session.rs |
Stores per-session anticipated counts and closing state. |
neqo-http3/src/features/extended_connect/tests/webtransport/mod.rs |
Registers the new test module. |
neqo-http3/src/features/extended_connect/tests/webtransport/anticipated_streams.rs |
Tests validation, aggregation, limits, closure, and capacity. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4011 +/- ##
==========================================
- Coverage 97.19% 97.04% -0.15%
==========================================
Files 113 118 +5
Lines 41742 42161 +419
Branches 41742 42161 +419
==========================================
+ Hits 40570 40917 +347
- Misses 1156 1220 +64
- Partials 16 24 +8
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Merging this PR will degrade performance by 1.05%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Walltime | walltime/pacing-true/same-seed |
4.3 ms | 4.5 ms | -4.86% |
| ❌ | CPU Simulation | simulated/pacing-true/varying-seeds |
58.2 ms | 60.4 ms | -3.79% |
| ❌ | Walltime | 1-conn/1-100mb-req (aka. Upload) |
59 ms | 60.3 ms | -2.16% |
| ❌ | Walltime | walltime/pacing-false/same-seed |
3.7 ms | 3.8 ms | -2.05% |
| ⚡ | Walltime | walltime/pacing-true/varying-seeds |
4.6 ms | 4.4 ms | +4.65% |
| ⚡ | Walltime | walltime/1000-streams/each-1-bytes |
4.6 ms | 4.5 ms | +2.26% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing users/jesup/anticipated_incoming_streams (cbbb263) with main (e0f8bbf)
|
For the record, not required for Interop 2026, thus I will delay reviewing. Ping me in case I am missing something. |
I stand corrected. It is required for Interop 2026. |
435fa81 to
7c9dbf5
Compare
c40f3ca to
b34babe
Compare
Performance profiles for profiler.firefox.comBenchmarks (14)
|
mxinden
left a comment
There was a problem hiding this comment.
In the future, we might want to update the transport stream limit on session closing. I don't think introducing the complexity today is worth it, i.e. pull request is fine as is.
d9d75c2 to
dff942e
Compare
df25786 to
abf9452
Compare
dff942e to
c7a0cd2
Compare
abf9452 to
b9ffdcb
Compare
c7a0cd2 to
d59950a
Compare
b9ffdcb to
f46dc00
Compare
d59950a to
14f49ee
Compare
f46dc00 to
00989db
Compare
14f49ee to
8ff9868
Compare
00989db to
0b55226
Compare
8ff9868 to
c6eaaef
Compare
0b55226 to
06b7327
Compare
|
@jesup friendly ping for the comments above. |
…ms support
The spec lets an application supply, at session construction, how
many incoming streams of each type it expects the peer to open
concurrently, so the transport can grant that much headroom up front
rather than only after the peer bumps into the default limit and
waits a round trip for MAX_STREAMS.
webtransport_set_anticipated_incoming_{uni,bidi}_streams stores the
per-session value and recomputes the connection-wide total across
every not-yet-closed WebTransport session, clamped to
MAX_ANTICIPATED_INCOMING_STREAMS so an application cannot ratchet the
advertised limit arbitrarily high (it is monotonic and never comes
back down as sessions close). The unidirectional total also adds
HTTP3_UNI_CONTROL_STREAMS, since HTTP/3's own control and QPACK
streams draw from the same limit. Closed sessions are excluded from
the sum; sessions still negotiating are included, since that is
exactly when the API supplies this value.
Client-only: the anticipated-streams attributes are on the
WebTransport interface, which has no server-side equivalent.
06b7327 to
cbbb263
Compare
Client/server transfer resultsPerformance differences relative to e0f8bbf. Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.
Table above only shows statistically significant changes. See all results below. All resultsTransfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.
Download data for |
Benchmark resultsNo significant performance differences relative to e0f8bbf. All resultstransfer/1-conn/1-100mb-req (aka. Upload)/mtu-1500 time: [60.218 ms 60.280 ms 60.342 ms]
thrpt: [1.6184 GiB/s 1.6201 GiB/s 1.6217 GiB/s]transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1500 time: [60.595 ms 60.642 ms 60.691 ms]
thrpt: [1.6091 GiB/s 1.6104 GiB/s 1.6116 GiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mildtransfer/1-conn/1-1b-resp (aka. HPS)/mtu-1500 time: [3.5476 ms 3.5482 ms 3.5489 ms]
thrpt: [281.78 B/s 281.83 B/s 281.88 B/s]
Found 5 outliers among 100 measurements (5.00%)
3 (3.00%) high mild
2 (2.00%) high severetransfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1500 time: [81.104 ms 81.243 ms 81.387 ms]
thrpt: [122.87 Kelem/s 123.09 Kelem/s 123.30 Kelem/s]
Found 3 outliers among 100 measurements (3.00%)
3 (3.00%) high mildstreams-flow-controlled/walltime/1-streams/each-4194304-bytes time: [13.127 ms 13.132 ms 13.136 ms]
thrpt: [304.51 MiB/s 304.61 MiB/s 304.70 MiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mildstreams-flow-controlled/walltime/10-streams/each-1048576-bytes time: [33.836 ms 33.852 ms 33.868 ms]
thrpt: [295.27 MiB/s 295.40 MiB/s 295.54 MiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mildstreams/walltime/1-streams/each-1000-bytes time: [156.06 µs 156.67 µs 157.45 µs]
thrpt: [6.0572 MiB/s 6.0873 MiB/s 6.1109 MiB/s]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mildstreams/walltime/1000-streams/each-1-bytes time: [4.4608 ms 4.4654 ms 4.4700 ms]
thrpt: [218.47 KiB/s 218.70 KiB/s 218.92 KiB/s]
Found 5 outliers among 100 measurements (5.00%)
2 (2.00%) low mild
3 (3.00%) high mildstreams/walltime/1000-streams/each-1000-bytes time: [14.802 ms 14.812 ms 14.823 ms]
thrpt: [64.336 MiB/s 64.384 MiB/s 64.429 MiB/s]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mildtransfer/walltime/pacing-false/same-seed time: [3.8967 ms 3.8990 ms 3.9016 ms]
thrpt: [1.0012 GiB/s 1.0019 GiB/s 1.0024 GiB/s]transfer/walltime/pacing-false/varying-seeds time: [3.9232 ms 3.9250 ms 3.9272 ms]
thrpt: [1018.5 MiB/s 1019.1 MiB/s 1019.6 MiB/s]transfer/walltime/pacing-true/same-seed time: [4.1942 ms 4.1962 ms 4.1986 ms]
thrpt: [952.70 MiB/s 953.25 MiB/s 953.70 MiB/s]transfer/walltime/pacing-true/varying-seeds time: [4.0688 ms 4.0723 ms 4.0765 ms]
thrpt: [981.24 MiB/s 982.24 MiB/s 983.08 MiB/s]Instructions per cycleCriterion reported no significant timing changes. All benchmarks
Profiles for profiler.firefox.com (64)
Download data for |
Failed Interop TestsQUIC Interop Runner, client vs. server, differences relative to
All resultsSucceeded Interop TestsQUIC Interop Runner, client vs. server neqo-pr as client
neqo-pr as server
Unsupported Interop TestsQUIC Interop Runner, client vs. server neqo-pr as client
neqo-pr as server
|

Implements
anticipatedConcurrentIncomingUnidirectionalStreams/anticipatedConcurrentIncomingBidirectionalStreamson the client:webtransport_set_anticipated_incoming_{uni,bidi}_streamsstore a per-session value and raise the connection's incoming stream limit (viaConnection::set_remote_max_streamsfrom #4010) to the sum over WebTransport sessions that are not closing, so the peer gets that headroom up front instead of waiting a round trip forMAX_STREAMS.InvalidStreamId.MAX_ANTICIPATED_INCOMING_STREAMS(10,000) so pages cannot ratchet the monotonic limit arbitrarily high; the unidirectional limit adds HTTP/3's own three control/QPACK streams on top.