Skip to content

WebTransport: expose outgoing datagram queue capacity per session - #3993

Closed
jesup wants to merge 1 commit into
users/jesup/drop_datagrams_on_teardownfrom
users/jesup/expose_queue_capacity
Closed

jesup wants to merge 1 commit into
users/jesup/drop_datagrams_on_teardownfrom
users/jesup/expose_queue_capacity

Conversation

@jesup

@jesup jesup commented Sep 14, 2026 •

Copy link
Copy Markdown
Member

Add ClientSession::webtransport_datagram_queue_capacity, so a caller (Firefox's content-process credit grant) can read a WebTransport session's outgoing-datagram queue state. The transport's DatagramQueueCapacity snapshot and the per-session accessor already existed behind #[cfg(test)]; this drops that and validates the session as WebTransport, so a connect-udp session id is rejected.

@jesup

jesup commented Sep 14, 2026 •

Copy link
Copy Markdown
Member Author

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The required public trait method is source-breaking, and the new test documentation misidentifies the queue layer.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Exposes per-session WebTransport outgoing-datagram queue capacity for content-process credit management.

Changes:

  • Adds a client-facing capacity query.
  • Makes internal capacity lookup available in production.
  • Tests queue accounting beyond the legacy FIFO size.
File summaries
File Description
neqo-http3/src/webtransport.rs Adds the client capacity API and delegation.
neqo-http3/src/connection.rs Adds validated WebTransport capacity lookup.
neqo-http3/src/features/extended_connect/session.rs Enables production access to session capacity.
neqo-http3/src/features/extended_connect/tests/webtransport/datagrams.rs Tests per-session queue capacity accounting.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 2
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread neqo-http3/src/webtransport.rs
Comment thread neqo-http3/src/features/extended_connect/tests/webtransport/datagrams.rs Outdated
@codecov

codecov Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.93%. Comparing base (dc976e1) to head (f333aef).

Additional details and impacted files
@@                           Coverage Diff                           @@
##           users/jesup/drop_datagrams_on_teardown    #3993   +/-   ##
=======================================================================
  Coverage                                   96.93%   96.93%           
=======================================================================
  Files                                         119      119           
  Lines                                       41579    41584    +5     
  Branches                                    41579    41584    +5     
=======================================================================
+ Hits                                        40303    40309    +6     
+ Misses                                       1252     1251    -1     
  Partials                                       24       24           
Flag Coverage Δ
freebsd 94.46% <100.00%> (+<0.01%) ⬆️
linux 97.14% <100.00%> (-0.01%) ⬇️
macos 95.30% <100.00%> (+<0.01%) ⬆️
windows 95.38% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
neqo-common 99.31% <ø> (ø)
neqo-http3 95.41% <100.00%> (+<0.01%) ⬆️
neqo-qpack 96.97% <ø> (ø)
neqo-transport 97.89% <ø> (ø)
neqo-udp 95.37% <ø> (ø)
mtu 89.13% <ø> (ø)

@codspeed

codspeed Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will regress 1 benchmark

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 5 improved benchmarks
❌ 1 regressed benchmark
✅ 93 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ WallTime walltime/1-streams/each-4194304-bytes 10.6 ms 11 ms -2.98%
⚡ Simulation coalesce_acked_from_zero 1 ranges 2.8 µs 2.7 µs +3.96%
⚡ Simulation coalesce_acked_from_zero 3 ranges 3.7 µs 3.6 µs +2.98%
⚡ WallTime neqo-neqo-cubic 20.9 ms 20.3 ms +2.68%
⚡ WallTime 1-conn/1-1b-resp (aka. HPS) 3 ms 2.9 ms +2.07%
⚡ WallTime 1-conn/1-100mb-resp (aka. Download) 48.2 ms 47.3 ms +2.05%

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/expose_queue_capacity (f333aef) with users/jesup/drop_datagrams_on_teardown (dc976e1)

Open in CodSpeed

@jesup
jesup force-pushed the users/jesup/drop_datagrams_on_teardown branch from 0436765 to 6d838db Compare September 14, 2026 05:31
@jesup
jesup requested a review from omansfeld as a code owner September 14, 2026 05:31
@jesup
jesup force-pushed the users/jesup/expose_queue_capacity branch from e4297ad to b3cb781 Compare September 14, 2026 05:31
@jesup
jesup force-pushed the users/jesup/drop_datagrams_on_teardown branch from 6d838db to e919805 Compare September 14, 2026 17:56
@jesup
jesup force-pushed the users/jesup/expose_queue_capacity branch from b3cb781 to f686bf9 Compare September 14, 2026 17:56
@jesup
jesup force-pushed the users/jesup/drop_datagrams_on_teardown branch from e919805 to 6c8995d Compare September 16, 2026 03:45
@jesup
jesup force-pushed the users/jesup/expose_queue_capacity branch from f686bf9 to 816d884 Compare September 16, 2026 03:45
mxinden-bot pushed a commit to mxinden-bot/neqo that referenced this pull request Sep 16, 2026
Written against the tip of the per-session datagram queue stack (mozilla#3993).
All four fail; the other 943 neqo-transport lib tests pass.

DatagramQueue::enqueue never expires, so a datagram already past its max
age still counts against the byte budget and the high water mark. It is
reported Dropped rather than Expired, mis-attributing the stat and giving
the application backpressure whose real cause was age, not depth. The
previous stack fixed this in Session::send_datagram; the rewrite lost it.
Fixing it in place needs default_max_age stored on the queue rather than
threaded in as a parameter.

QuicDatagrams::set_datagram_high_water_mark does not call
resume_if_unblocked, unlike set_datagram_max_age right above it, so an
application that raises outgoingMaxBufferedDatagrams while blocked waits
until a send or an expiry happens to revisit the queue.

A high water mark of zero wedges the sender permanently: below_watermark
is total_count < mark, false at every count, so resume_if_unblocked can
never fire. Arguably faithful to a degenerate corner of the spec, so this
one is a question rather than a defect.
Comment thread neqo-http3/src/features/extended_connect/tests/webtransport/datagrams.rs Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Performance profiles for profiler.firefox.com

Benchmarks (14)
  • neqo-bin-main: pr · base
  • neqo-common-decoder: pr · base
  • neqo-http3-streams_simulated: pr · base
  • neqo-http3-streams_walltime: pr · base
  • neqo-transport-frame_decode: pr · base
  • neqo-transport-min_bandwidth: pr · base
  • neqo-transport-pacer: pr · base
  • neqo-transport-packet_codec: pr · base
  • neqo-transport-range_tracker: pr · base
  • neqo-transport-rx_stream_orderer: pr · base
  • neqo-transport-send_streams: pr · base
  • neqo-transport-sent_packets: pr · base
  • neqo-transport-transfer_simulated: pr · base
  • neqo-transport-transfer_walltime: pr · base
Comparisons (5)

@jesup
jesup force-pushed the users/jesup/drop_datagrams_on_teardown branch from 609dbad to f3f6e7c Compare September 23, 2026 23:55
@jesup
jesup force-pushed the users/jesup/expose_queue_capacity branch from 1cb9ec5 to b172928 Compare September 23, 2026 23:55
@jesup
jesup force-pushed the users/jesup/drop_datagrams_on_teardown branch from f3f6e7c to b3f7e86 Compare September 25, 2026 10:28
@jesup
jesup force-pushed the users/jesup/expose_queue_capacity branch from b172928 to c0707d8 Compare September 25, 2026 10:28
@jesup
jesup force-pushed the users/jesup/drop_datagrams_on_teardown branch from b3f7e86 to fad8dba Compare September 25, 2026 12:35
@jesup
jesup force-pushed the users/jesup/expose_queue_capacity branch from c0707d8 to c245d30 Compare September 25, 2026 12:35
@jesup
jesup force-pushed the users/jesup/drop_datagrams_on_teardown branch from fad8dba to 37fdffd Compare September 25, 2026 15:05
@jesup
jesup force-pushed the users/jesup/expose_queue_capacity branch 2 times, most recently from 419a6ae to 5a2f7b1 Compare September 30, 2026 03:30
@jesup
jesup force-pushed the users/jesup/drop_datagrams_on_teardown branch 2 times, most recently from 5f27707 to 0415ed4 Compare September 30, 2026 15:32
@jesup
jesup force-pushed the users/jesup/expose_queue_capacity branch from 5a2f7b1 to 41cc958 Compare September 30, 2026 15:32
Comment thread neqo-http3/src/connection.rs
Add a production-facing Http3Client::webtransport_datagram_queue_capacity,
so a caller (e.g. a content-process credit grant) can read a session's
outgoing-datagram queue state without going through the test-only path.
The underlying transport-level DatagramQueueCapacity snapshot and
per-session accessor already existed but were only reachable from
#[cfg(test)] code; drop that gate now that there's a real caller.
@jesup
jesup force-pushed the users/jesup/drop_datagrams_on_teardown branch from 0415ed4 to dc976e1 Compare October 2, 2026 21:48
@jesup
jesup force-pushed the users/jesup/expose_queue_capacity branch from 41cc958 to f333aef Compare October 2, 2026 21:48
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Client/server transfer results

Performance differences relative to dc976e1.

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server Mean±σ Min–Max Median±MAD MiB/s±σ ΔMedian
google-neqo-cubic 72.0 ± 0.5 70.6 – 73.1 72.0 ± 0.4 444.4 ± 2.8 💔 +2.8 (+4.1%)
neqo-neqo-newreno 19.3 ± 0.2 19.0 – 19.8 19.3 ± 0.2 1657.9 ± 13.6 💚 -0.2 (-1.0%)

Table above only shows statistically significant changes. See all results below.

All results

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server Mean±σ Min–Max Median±MAD MiB/s±σ ΔMedian
google-google 133.2 ± 0.6 131.7 – 134.5 133.2 ± 0.8 240.3 ± 1.2
google-neqo-cubic 72.0 ± 0.5 70.6 – 73.1 72.0 ± 0.4 444.4 ± 2.8 💔 +2.8 (+4.1%)
neqo-google-cubic 226.0 ± 30.6 167.5 – 316.0 225.6 ± 33.0 141.6 ± 19.2 +5.4 (+2.4%)
neqo-neqo-cubic 19.7 ± 0.2 19.2 – 20.1 19.6 ± 0.2 1628.3 ± 14.7 -0.1 (-0.6%)
neqo-neqo-cubic-nopacing 18.7 ± 0.2 18.3 – 19.3 18.7 ± 0.2 1709.9 ± 19.2 -0.0 (-0.0%)
neqo-neqo-newreno 19.3 ± 0.2 19.0 – 19.8 19.3 ± 0.2 1657.9 ± 13.6 💚 -0.2 (-1.0%)
neqo-neqo-newreno-nopacing 19.3 ± 0.2 18.9 – 19.9 19.3 ± 0.2 1654.3 ± 18.3 +0.1 (+0.3%)
neqo-quiche-cubic 33.6 ± 0.3 33.1 – 34.2 33.6 ± 0.3 952.5 ± 7.5 +0.2 (+0.6%)
neqo-s2n-cubic 38.0 ± 0.2 37.5 – 38.6 38.0 ± 0.2 841.2 ± 4.9 -0.0 (-0.0%)
quiche-neqo-cubic 38.2 ± 0.3 37.6 – 39.5 38.2 ± 0.3 836.7 ± 7.6 +0.1 (+0.1%)
quiche-quiche 39.6 ± 0.2 39.2 – 40.3 39.6 ± 0.2 808.1 ± 4.3
s2n-neqo-cubic 112.8 ± 0.3 112.3 – 114.3 112.8 ± 0.3 283.7 ± 0.8 +0.1 (+0.1%)
s2n-s2n ⚠️ 165.1 ± 25.4 135.2 – 284.6 160.1 ± 1.0 193.8 ± 29.8

Download data for profiler.firefox.com or download performance comparison data.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Failed Interop Tests

QUIC Interop Runner, client vs. server, differences relative to users/jesup/drop_datagrams_on_teardown at dc976e1.

neqo-pr as clientneqo-pr as server
neqo-pr vs. go-x-net: BP BA
neqo-pr vs. haproxy: ⚠️M BP BA
neqo-pr vs. kwik: C20 🚀S 3 A ⚠️M Z B L1 C1 ⚠️C2
neqo-pr vs. lsquic: baseline result missing
neqo-pr vs. msquic: Z A L1 🚀L2 C1
neqo-pr vs. mvfst: A BA
neqo-pr vs. neqo: Z A
neqo-pr vs. nginx: BP BA
neqo-pr vs. ngtcp2: Z L1 C1 CM
neqo-pr vs. picoquic: Z A 🚀BP
neqo-pr vs. quic-go: A 🚀C1
neqo-pr vs. quiche: BP BA
neqo-pr vs. s2n-quic: CM
neqo-pr vs. tquic: S BP BA
neqo-pr vs. xquic: S R Z A L1 C1
aioquic vs. neqo-pr: CM
go-x-net vs. neqo-pr: CM
kwik vs. neqo-pr: BP BA CM
msquic vs. neqo-pr: CM
mvfst vs. neqo-pr: Z L1 C1 CM
neqo vs. neqo-pr: Z A
openssl vs. neqo-pr: LR M A CM
quic-go vs. neqo-pr: CM
quic-zig vs. neqo-pr: CM
quiche vs. neqo-pr: ⚠️C1 CM
quinn vs. neqo-pr: 🚀L1 V2 CM
s2n-quic vs. neqo-pr: ⚠️B CM
tquic vs. neqo-pr: CM
xquic vs. neqo-pr: M CM
All results

Succeeded Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

Unsupported Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Benchmark results

No significant performance differences relative to dc976e1.

All results
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1500
       time:   [50.275 ms 50.311 ms 50.349 ms]
       thrpt:  [1.9396 GiB/s 1.9411 GiB/s 1.9425 GiB/s]
Found 8 outliers among 100 measurements (8.00%)
3 (3.00%) low mild
4 (4.00%) high mild
1 (1.00%) high severe
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1500
       time:   [49.505 ms 49.562 ms 49.621 ms]
       thrpt:  [1.9681 GiB/s 1.9704 GiB/s 1.9727 GiB/s]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1500
       time:   [3.0143 ms 3.0151 ms 3.0159 ms]
       thrpt:  [331.58   B/s 331.66   B/s 331.75   B/s]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) low mild
1 (1.00%) high mild
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1500
       time:   [68.304 ms 68.560 ms 68.817 ms]
       thrpt:  [145.31 Kelem/s 145.86 Kelem/s 146.40 Kelem/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
streams-flow-controlled/walltime/1-streams/each-4194304-bytes
       time:   [11.038 ms 11.040 ms 11.043 ms]
       thrpt:  [362.22 MiB/s 362.31 MiB/s 362.40 MiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
streams-flow-controlled/walltime/10-streams/each-1048576-bytes
       time:   [28.101 ms 28.110 ms 28.119 ms]
       thrpt:  [355.63 MiB/s 355.75 MiB/s 355.86 MiB/s]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
streams/walltime/1-streams/each-1000-bytes
       time:   [131.63 µs 132.17 µs 132.87 µs]
       thrpt:  [7.1777 MiB/s 7.2153 MiB/s 7.2449 MiB/s]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
streams/walltime/1000-streams/each-1-bytes
       time:   [3.8203 ms 3.8323 ms 3.8439 ms]
       thrpt:  [254.06 KiB/s 254.82 KiB/s 255.63 KiB/s]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) low mild
streams/walltime/1000-streams/each-1000-bytes
       time:   [11.223 ms 11.227 ms 11.231 ms]
       thrpt:  [84.917 MiB/s 84.945 MiB/s 84.974 MiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
transfer/walltime/pacing-false/same-seed
       time:   [2.0144 ms 2.0158 ms 2.0174 ms]
       thrpt:  [1.9362 GiB/s 1.9378 GiB/s 1.9392 GiB/s]
transfer/walltime/pacing-false/varying-seeds
       time:   [2.0127 ms 2.0137 ms 2.0151 ms]
       thrpt:  [1.9385 GiB/s 1.9398 GiB/s 1.9408 GiB/s]
transfer/walltime/pacing-true/same-seed
       time:   [2.1079 ms 2.1100 ms 2.1125 ms]
       thrpt:  [1.8491 GiB/s 1.8513 GiB/s 1.8531 GiB/s]
transfer/walltime/pacing-true/varying-seeds
       time:   [2.0628 ms 2.0636 ms 2.0646 ms]
       thrpt:  [1.8920 GiB/s 1.8929 GiB/s 1.8936 GiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild

Instructions per cycle

Criterion reported no significant timing changes.

All benchmarks
Benchmark IPC before IPC after ΔIPC
streams-flow-controlled/walltime/10-streams/each-1048576-bytes 3.23 3.20 -1.0%
streams-flow-controlled/walltime/1-streams/each-4194304-bytes 2.97 2.94 -0.9%
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1500 3.25 3.23 -0.5%
streams/walltime/1000-streams/each-1000-bytes 3.09 3.11 +0.4%
transfer/walltime/pacing-false/same-seed 2.87 2.88 +0.4%
transfer/walltime/pacing-true/same-seed 2.88 2.87 -0.4%
streams/walltime/1-streams/each-1000-bytes 2.51 2.52 +0.3%
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1500 3.20 3.20 -0.2%
transfer/walltime/pacing-false/varying-seeds 2.88 2.88 +0.1%
streams/walltime/1000-streams/each-1-bytes 3.29 3.29 +0.1%
transfer/walltime/pacing-true/varying-seeds 2.89 2.89 -0.0%
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1500 2.24 2.24 -0.0%
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1500 3.23 3.23 -0.0%
Profiles for profiler.firefox.com (62)

Download data for profiler.firefox.com or download performance comparison data.

@jesup
jesup deleted the branch users/jesup/drop_datagrams_on_teardown October 3, 2026 02:13
@jesup jesup closed this Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants