Skip to content

SCONE#2814

Merged
larseggert merged 66 commits into
mozilla:mainfrom
martinthomson:scone
Mar 13, 2026
Merged

SCONE#2814
larseggert merged 66 commits into
mozilla:mainfrom
martinthomson:scone

Conversation

@martinthomson
Copy link
Copy Markdown
Member

This turned out to be relatively easy to implement.

Does doesn't do anything with the SCONE indications that are received; as this is intended for use in a browser, there isn't an easy way to plumb those through to something that might use those indications. For the moment, these are just logged.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jul 30, 2025

Codecov Report

❌ Patch coverage is 95.76271% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.00%. Comparing base (70a0ba6) to head (07e4f68).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2814      +/-   ##
==========================================
- Coverage   94.12%   94.00%   -0.12%     
==========================================
  Files         125      129       +4     
  Lines       38339    38735     +396     
  Branches    38339    38735     +396     
==========================================
+ Hits        36086    36413     +327     
- Misses       1412     1473      +61     
- Partials      841      849       +8     
Flag Coverage Δ
freebsd 93.05% <94.06%> (-0.10%) ⬇️
linux 94.10% <95.76%> (+<0.01%) ⬆️
macos 94.00% <95.76%> (-0.01%) ⬇️
windows 94.09% <95.76%> (+<0.01%) ⬆️

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

Components Coverage Δ
neqo-common 98.54% <ø> (ø)
neqo-crypto 86.90% <ø> (ø)
neqo-http3 93.91% <ø> (ø)
neqo-qpack 94.34% <ø> (ø)
neqo-transport 94.93% <95.76%> (-0.04%) ⬇️
neqo-udp 82.97% <ø> (ø)
mtu 86.61% <ø> (ø)

Comment thread neqo-transport/src/connection/params.rs
Comment thread neqo-transport/src/connection/params.rs Outdated
Comment thread neqo-transport/src/packet/mod.rs Outdated
Comment thread neqo-transport/src/connection/mod.rs
Comment thread neqo-transport/src/connection/mod.rs
Comment thread neqo-transport/src/connection/mod.rs
Comment thread neqo-transport/src/connection/mod.rs Outdated
Comment thread neqo-transport/src/connection/mod.rs
Comment thread neqo-transport/src/connection/mod.rs Outdated
Comment thread neqo-transport/src/connection/mod.rs
Comment thread neqo-transport/src/connection/mod.rs
Comment thread neqo-transport/src/packet/mod.rs
@martinthomson
Copy link
Copy Markdown
Member Author

I'm still stumped on the performance hit here. Any ideas?

@mxinden
Copy link
Copy Markdown
Member

mxinden commented Jul 30, 2025

Nothing comes to mind. I will try to reproduce locally.

@mxinden
Copy link
Copy Markdown
Member

mxinden commented Jul 30, 2025

Hypothesis:

  • We no longer pad with 0x00s, but 0xc8 instead.
  • 0x00 padding is filtered out early in our processing pipeline
    if first & 0x80 == PACKET_BIT_SHORT {
    // Conveniently, this also guarantees that there is enough space
    // for a connection ID of any size.
    if decoder.remaining() < SAMPLE_OFFSET + SAMPLE_SIZE {
    return Err(Error::InvalidPacket);
    }
    let dcid = Self::opt(dcid_decoder.decode_cid(&mut decoder))?.into();
    if decoder.remaining() < SAMPLE_OFFSET + SAMPLE_SIZE {
    return Err(Error::InvalidPacket);
    }
  • 0xc8 is interpreted as a long packet, then later on discarded.
  • I assume the additional processing itself is expensive. In addition we now have a qwarn! triggering in our hot path.
    self.stats
    .borrow_mut()
    .pkt_dropped("Coalesced packet has different DCID");
  • Executing the transfer benchmark locally, stdout is spammed with the qwarn! above.

Can we special case 0xc8 in packet/mod.rs encode to discard the SCONE padding early @martinthomson?

@larseggert
Copy link
Copy Markdown
Collaborator

We should also add a preference for this (default on).

@martinthomson
Copy link
Copy Markdown
Member Author

I'm not sure about that hypothesis: we don't send these packets very often and an all-0xc8 packet usually fails decryption (because it's a long header packet with a connection ID longer than the remaining bytes). That's FASTER path to rejecting the packet than attempting to decrypt a short header packet.

As for the qwarn!(), we should downgrade that to qinfo!() or even qdebug!(), because dropping packets is totally normal. I'll try that out.

@martinthomson
Copy link
Copy Markdown
Member Author

Oh, I just realized what might be going on here:

let Ok(version) = Version::try_from(version) else {
return Ok((
Self {
packet_type: Type::OtherVersion,
dcid,
scid: Some(scid),
token: vec![],
header_len: decoder.offset(),
version: Some(version),
data,
},
&mut [],
));
};

This might be more work than following the short header path. Maybe this needs a flag where that option produces an error instead. That code only makes sense in the very early phases of server setup.

@martinthomson
Copy link
Copy Markdown
Member Author

Testing on my machine shows less-than-ideal performance, hinting at a slowdown, but I can't spot the problem still:

$ target/release/deps/transfer-ea5f6c8313464190 --bench -b main
transfer/pacing-false/varying-seeds
                        time:   [20.598 ms 20.658 ms 20.723 ms]
                        change: [−0.1420% +0.3377% +0.8482%] (p = 0.18 > 0.05)
                        No change in performance detected.
Found 3 outliers among 100 measurements (3.00%)
  2 (2.00%) high mild
  1 (1.00%) high severe

transfer/pacing-true/varying-seeds
                        time:   [20.808 ms 20.894 ms 20.988 ms]
                        change: [+1.8460% +2.2808% +2.7827%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 11 outliers among 100 measurements (11.00%)
  8 (8.00%) high mild
  3 (3.00%) high severe

transfer/pacing-false/same-seed
                        time:   [20.479 ms 20.539 ms 20.608 ms]
                        change: [+0.9765% +1.3664% +1.7723%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 7 outliers among 100 measurements (7.00%)
  1 (1.00%) high mild
  6 (6.00%) high severe

transfer/pacing-true/same-seed
                        time:   [20.728 ms 20.785 ms 20.847 ms]
                        change: [−0.0452% +0.3311% +0.6927%] (p = 0.08 > 0.05)
                        No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) high mild
  1 (1.00%) high severe

@mxinden
Copy link
Copy Markdown
Member

mxinden commented Jul 31, 2025

For what it is worth, I too am unable to reproduce the regression locally with the latest patches. Here using the Download benchmark:

critcmp main scone    
group                                         main                                   scone
-----                                         ----                                   -----
1-conn/1-100mb-resp (aka. Download)/client    1.01    299.1±6.00ms   334.3 MB/sec    1.00    297.1±3.57ms   336.6 MB/sec

@larseggert
Copy link
Copy Markdown
Collaborator

Do the flamegraphs look different?

@martinthomson
Copy link
Copy Markdown
Member Author

@mxinden, are you able to help out here? I know that this isn't high priority, but I really can't see how this change would materially affect performance. I'm unable to get flamegraphs from my machine easily, so your help would be appreciated.

@larseggert
Copy link
Copy Markdown
Collaborator

I'm unable to get flamegraphs from my machine easily, so your help would be appreciated.

You can "Download data for profiler.firefox.com" and then (with samply installed do, for example,

samply load neqo-neqo-cubic.client.perf.samply.json.gz

Comment thread neqo-transport/src/connection/mod.rs Outdated
@larseggert
Copy link
Copy Markdown
Collaborator

Blocked by lack of final IANA codepoints.

@larseggert
Copy link
Copy Markdown
Collaborator

@martinthomson any news re: IANA codepoints?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Nov 2, 2025

🐰 Bencher Report

Branchscone
TestbedOn-prem

🚨 3 Alerts

IterationBenchmarkMeasure
Units
ViewBenchmark Result
(Result Δ%)
Upper Boundary
(Limit %)
0google vs. neqo (cubic, paced)Latency
milliseconds (ms)
📈 plot
🚷 threshold
🚨 alert (🔔)
281.26 ms
(+1.25%)Baseline: 277.80 ms
280.93 ms
(100.12%)

2neqo vs. google (cubic, paced)Latency
milliseconds (ms)
📈 plot
🚷 threshold
🚨 alert (🔔)
770.01 ms
(+1.61%)Baseline: 757.79 ms
766.53 ms
(100.45%)

4neqo vs. neqo (cubic)Latency
milliseconds (ms)
📈 plot
🚷 threshold
🚨 alert (🔔)
96.32 ms
(+5.95%)Baseline: 90.92 ms
95.70 ms
(100.65%)

Click to view all benchmark results
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
google vs. neqo (cubic, paced)📈 view plot
🚷 view threshold
🚨 view alert (🔔)
281.26 ms
(+1.25%)Baseline: 277.80 ms
280.93 ms
(100.12%)

BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
msquic vs. neqo (cubic, paced)📈 view plot
🚷 view threshold
202.26 ms
(+2.25%)Baseline: 197.80 ms
234.78 ms
(86.15%)
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
neqo vs. google (cubic, paced)📈 view plot
🚷 view threshold
🚨 view alert (🔔)
770.01 ms
(+1.61%)Baseline: 757.79 ms
766.53 ms
(100.45%)

BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
neqo vs. msquic (cubic, paced)📈 view plot
🚷 view threshold
159.72 ms
(+1.23%)Baseline: 157.78 ms
160.78 ms
(99.34%)
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
neqo vs. neqo (cubic)📈 view plot
🚷 view threshold
🚨 view alert (🔔)
96.32 ms
(+5.95%)Baseline: 90.92 ms
95.70 ms
(100.65%)

BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
neqo vs. neqo (cubic, paced)📈 view plot
🚷 view threshold
96.76 ms
(+4.81%)Baseline: 92.32 ms
97.06 ms
(99.69%)
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
neqo vs. neqo (reno)📈 view plot
🚷 view threshold
94.80 ms
(+4.18%)Baseline: 90.99 ms
95.81 ms
(98.95%)
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
neqo vs. neqo (reno, paced)📈 view plot
🚷 view threshold
96.69 ms
(+4.82%)Baseline: 92.25 ms
96.90 ms
(99.78%)
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
neqo vs. quiche (cubic, paced)📈 view plot
🚷 view threshold
193.63 ms
(-0.04%)Baseline: 193.71 ms
197.11 ms
(98.24%)
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
neqo vs. s2n (cubic, paced)📈 view plot
🚷 view threshold
223.81 ms
(+1.28%)Baseline: 220.98 ms
223.89 ms
(99.97%)
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
quiche vs. neqo (cubic, paced)📈 view plot
🚷 view threshold
154.09 ms
(+0.68%)Baseline: 153.05 ms
158.41 ms
(97.27%)
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
s2n vs. neqo (cubic, paced)📈 view plot
🚷 view threshold
173.37 ms
(-0.44%)Baseline: 174.14 ms
178.20 ms
(97.29%)
🐰 View full continuous benchmarking report in Bencher

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Nov 2, 2025

🐰 Bencher Report

Branchscone
TestbedOn-prem
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
nanoseconds (ns)
(Result Δ%)
Upper Boundary
nanoseconds (ns)
(Limit %)
1-conn/1-100mb-req/mtu-1504 (aka. Upload)/client📈 view plot
🚷 view threshold
202,590,000.00 ns
(-2.09%)Baseline: 206,915,535.71 ns
217,159,737.21 ns
(93.29%)
1-conn/1-100mb-resp/mtu-1504 (aka. Download)/client📈 view plot
🚷 view threshold
198,750,000.00 ns
(-1.08%)Baseline: 200,919,678.57 ns
211,977,656.90 ns
(93.76%)
1-conn/1-1b-resp/mtu-1504 (aka. HPS)/client📈 view plot
🚷 view threshold
38,614,000.00 ns
(+28.65%)Baseline: 30,014,553.57 ns
38,834,114.80 ns
(99.43%)
1-conn/10_000-parallel-1b-resp/mtu-1504 (aka. RPS)/client📈 view plot
🚷 view threshold
285,700,000.00 ns
(-2.18%)Baseline: 292,070,250.00 ns
304,889,871.10 ns
(93.71%)
1-streams/each-1000-bytes/simulated-time📈 view plot
🚷 view threshold
118,970,000.00 ns
(+0.32%)Baseline: 118,588,857.14 ns
120,800,869.77 ns
(98.48%)
1-streams/each-1000-bytes/wallclock-time📈 view plot
🚷 view threshold
589,410.00 ns
(-0.79%)Baseline: 594,113.93 ns
618,038.86 ns
(95.37%)
1000-streams/each-1-bytes/simulated-time📈 view plot
🚷 view threshold
14,994,000,000.00 ns
(+0.00%)Baseline: 14,993,371,428.57 ns
15,011,666,803.43 ns
(99.88%)
1000-streams/each-1-bytes/wallclock-time📈 view plot
🚷 view threshold
13,606,000.00 ns
(-2.97%)Baseline: 14,022,064.29 ns
14,893,959.05 ns
(91.35%)
1000-streams/each-1000-bytes/simulated-time📈 view plot
🚷 view threshold
18,943,000,000.00 ns
(-0.08%)Baseline: 18,958,367,857.14 ns
19,233,360,057.78 ns
(98.49%)
1000-streams/each-1000-bytes/wallclock-time📈 view plot
🚷 view threshold
47,697,000.00 ns
(-6.27%)Baseline: 50,887,767.86 ns
57,642,611.62 ns
(82.75%)
RxStreamOrderer::inbound_frame()📈 view plot
🚷 view threshold
109,100,000.00 ns
(-0.50%)Baseline: 109,643,642.86 ns
111,661,047.44 ns
(97.71%)
coalesce_acked_from_zero 1+1 entries📈 view plot
🚷 view threshold
89.29 ns
(+0.70%)Baseline: 88.67 ns
89.53 ns
(99.74%)
coalesce_acked_from_zero 10+1 entries📈 view plot
🚷 view threshold
106.10 ns
(+0.06%)Baseline: 106.03 ns
107.11 ns
(99.06%)
coalesce_acked_from_zero 1000+1 entries📈 view plot
🚷 view threshold
91.37 ns
(+1.65%)Baseline: 89.88 ns
94.19 ns
(97.01%)
coalesce_acked_from_zero 3+1 entries📈 view plot
🚷 view threshold
106.23 ns
(-0.30%)Baseline: 106.55 ns
107.60 ns
(98.73%)
decode 1048576 bytes, mask 3f📈 view plot
🚷 view threshold
1,589,400.00 ns
(-2.45%)Baseline: 1,629,356.07 ns
1,796,685.47 ns
(88.46%)
decode 1048576 bytes, mask 7f📈 view plot
🚷 view threshold
5,053,000.00 ns
(-0.27%)Baseline: 5,066,498.57 ns
5,112,482.30 ns
(98.84%)
decode 1048576 bytes, mask ff📈 view plot
🚷 view threshold
3,034,400.00 ns
(+0.18%)Baseline: 3,028,805.36 ns
3,047,003.29 ns
(99.59%)
decode 4096 bytes, mask 3f📈 view plot
🚷 view threshold
5,541.20 ns
(-26.99%)Baseline: 7,589.43 ns
10,399.47 ns
(53.28%)
decode 4096 bytes, mask 7f📈 view plot
🚷 view threshold
19,456.00 ns
(-1.99%)Baseline: 19,851.86 ns
20,473.58 ns
(95.03%)
decode 4096 bytes, mask ff📈 view plot
🚷 view threshold
10,670.00 ns
(-6.75%)Baseline: 11,441.97 ns
12,557.73 ns
(84.97%)
sent::Packets::take_ranges📈 view plot
🚷 view threshold
4,546.10 ns
(-3.96%)Baseline: 4,733.55 ns
4,972.28 ns
(91.43%)
transfer/pacing-false/same-seed/simulated-time/run📈 view plot
🚷 view threshold
25,710,000,000.00 ns
(+1.14%)Baseline: 25,418,956,834.53 ns
26,071,176,299.93 ns
(98.61%)
transfer/pacing-false/same-seed/wallclock-time/run📈 view plot
🚷 view threshold
25,061,000.00 ns
(-3.14%)Baseline: 25,874,615.11 ns
27,028,139.12 ns
(92.72%)
transfer/pacing-false/varying-seeds/simulated-time/run📈 view plot
🚷 view threshold
25,172,000,000.00 ns
(-0.00%)Baseline: 25,172,341,726.62 ns
25,220,118,696.55 ns
(99.81%)
transfer/pacing-false/varying-seeds/wallclock-time/run📈 view plot
🚷 view threshold
24,513,000.00 ns
(-5.48%)Baseline: 25,934,906.47 ns
27,500,645.35 ns
(89.14%)
transfer/pacing-true/same-seed/simulated-time/run📈 view plot
🚷 view threshold
25,675,000,000.00 ns
(+0.18%)Baseline: 25,629,622,302.16 ns
25,731,312,433.86 ns
(99.78%)
transfer/pacing-true/same-seed/wallclock-time/run📈 view plot
🚷 view threshold
25,803,000.00 ns
(-5.06%)Baseline: 27,177,485.61 ns
28,686,876.26 ns
(89.95%)
transfer/pacing-true/varying-seeds/simulated-time/run📈 view plot
🚷 view threshold
24,954,000,000.00 ns
(-0.16%)Baseline: 24,993,672,661.87 ns
25,042,687,291.64 ns
(99.65%)
transfer/pacing-true/varying-seeds/wallclock-time/run📈 view plot
🚷 view threshold
24,942,000.00 ns
(-5.67%)Baseline: 26,441,928.06 ns
28,087,481.03 ns
(88.80%)
🐰 View full continuous benchmarking report in Bencher

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Nov 2, 2025

Failed Interop Tests

QUIC Interop Runner, client vs. server

neqo-latest as client

neqo-latest as server

All results

Succeeded Interop Tests

QUIC Interop Runner, client vs. server

neqo-latest as client

neqo-latest as server

Unsupported Interop Tests

QUIC Interop Runner, client vs. server

neqo-latest as client

neqo-latest as server

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Mar 12, 2026

Merging this PR will degrade performance by 20.14%

⚡ 1 improved benchmark
❌ 6 regressed benchmarks
✅ 44 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime google-google 1.2 s 1.2 s -5.42%
WallTime neqo-s2n 510.5 ms 606.9 ms -15.89%
WallTime quiche-neqo 345.8 ms 433 ms -20.14%
WallTime msquic-msquic 482.2 ms 459.4 ms +4.97%
WallTime neqo-neqo-newreno-nopacing 280 ms 300.3 ms -6.75%
WallTime neqo-neqo-cubic 292.2 ms 304.4 ms -4.02%
WallTime neqo-neqo-cubic-nopacing 283.4 ms 300.3 ms -5.65%

Comparing martinthomson:scone (07e4f68) with main (70a0ba6)

Open in CodSpeed

@larseggert
Copy link
Copy Markdown
Collaborator

@martinthomson is this now ready to review/land, or are we still waiting for IANA codepoints?

@martinthomson
Copy link
Copy Markdown
Member Author

So, I think we should land it, but I have not yet sent the email to IANA. I'm drafting it right now.

Comment thread neqo-transport/src/connection/tests/priority.rs
Comment thread neqo-transport/src/connection/tests/recovery.rs
Comment thread neqo-transport/src/connection/params.rs
Comment thread test-fixture/src/lib.rs
@github-actions
Copy link
Copy Markdown
Contributor

Failed Interop Tests

QUIC Interop Runner, client vs. server, differences relative to main at 70a0ba6.

neqo-pr as clientneqo-pr as server
neqo-pr vs. go-x-net: BP BA
neqo-pr vs. haproxy: 🚀C1 BP BA
neqo-pr vs. kwik: S L1 C1 BP BA
neqo-pr vs. lsquic: L1 C1
neqo-pr vs. msquic: A L1 C1
neqo-pr vs. mvfst: H DC LR M R Z 3 B U A L1 L2 C1 C2 6 BP BA
neqo-pr vs. neqo: Z A ⚠️BP
neqo-pr vs. nginx: BP BA
neqo-pr vs. ngtcp2: 🚀C1 CM
neqo-pr vs. picoquic: A ⚠️BP
neqo-pr vs. quic-go: A 🚀L1
neqo-pr vs. quiche: BP BA
neqo-pr vs. s2n-quic: ⚠️BP BA CM
neqo-pr vs. tquic: S BP BA
neqo-pr vs. xquic: A 🚀C1
aioquic vs. neqo-pr: Z CM
go-x-net vs. neqo-pr: CM
kwik vs. neqo-pr: Z BP BA CM
lsquic vs. neqo-pr: Z 🚀L1 C1
msquic vs. neqo-pr: Z 🚀BA CM
mvfst vs. neqo-pr: Z A L1 C1 CM
neqo vs. neqo-pr: Z A
openssl vs. neqo-pr: LR M A CM
picoquic vs. neqo-pr: Z CM
quic-go vs. neqo-pr: 🚀C1 ⚠️BP CM
quiche vs. neqo-pr: Z CM
quinn vs. neqo-pr: Z ⚠️L1 V2 CM
s2n-quic vs. neqo-pr: B ⚠️BA CM
tquic vs. neqo-pr: Z 🚀C1 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
Copy link
Copy Markdown
Contributor

Client/server transfer results

Performance differences relative to 70a0ba6.

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

Client vs. server (params) Mean ± σ Min Max MiB/s ± σ Δ main Δ main
neqo-google-cubic 757.0 ± 5.0 749.4 772.9 42.3 ± 6.4 💔 1.7 0.2%

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 (params) Mean ± σ Min Max MiB/s ± σ Δ main Δ main
google-google-nopacing 456.0 ± 4.4 450.5 476.8 70.2 ± 7.3
google-neqo-cubic 273.8 ± 4.4 265.6 281.7 116.9 ± 7.3 1.1 0.4%
msquic-msquic-nopacing 233.8 ± 107.4 142.3 583.6 136.8 ± 0.3
msquic-neqo-cubic 232.1 ± 86.7 154.8 564.9 137.9 ± 0.4 -16.9 -6.8%
neqo-google-cubic 757.0 ± 5.0 749.4 772.9 42.3 ± 6.4 💔 1.7 0.2%
neqo-msquic-cubic 159.8 ± 4.5 151.6 175.8 200.3 ± 7.1 0.5 0.3%
neqo-neqo-cubic 96.4 ± 4.5 86.7 106.2 332.0 ± 7.1 0.5 0.5%
neqo-neqo-cubic-nopacing 96.2 ± 4.1 85.6 103.5 332.6 ± 7.8 0.5 0.5%
neqo-neqo-newreno 97.2 ± 4.4 86.4 108.3 329.1 ± 7.3 -1.0 -1.0%
neqo-neqo-newreno-nopacing 95.8 ± 4.2 87.8 104.5 334.0 ± 7.6 -1.0 -1.0%
neqo-quiche-cubic 191.5 ± 4.3 186.1 213.9 167.1 ± 7.4 -0.4 -0.2%
neqo-s2n-cubic 220.5 ± 4.2 212.3 232.2 145.1 ± 7.6 1.2 0.6%
quiche-neqo-cubic 181.1 ± 5.7 169.6 209.2 176.7 ± 5.6 1.0 0.6%
quiche-quiche-nopacing 143.8 ± 4.1 136.7 157.5 222.5 ± 7.8
s2n-neqo-cubic 173.7 ± 4.7 163.9 183.2 184.2 ± 6.8 -0.4 -0.2%
s2n-s2n-nopacing 245.4 ± 19.7 233.0 344.0 130.4 ± 1.6

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

@github-actions
Copy link
Copy Markdown
Contributor

Benchmark results

No significant performance differences relative to 70a0ba6.

All results
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1504: No change in performance detected.
       time:   [197.93 ms 198.43 ms 199.02 ms]
       thrpt:  [502.46 MiB/s 503.95 MiB/s 505.23 MiB/s]
change:
       time:   [-0.0443% +0.2732% +0.6275] (p = 0.09 > 0.05)
       thrpt:  [-0.6236% -0.2725% +0.0443]
       No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) high mild
3 (3.00%) high severe
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1504: Change within noise threshold.
       time:   [283.03 ms 285.16 ms 287.38 ms]
       thrpt:  [34.797 Kelem/s 35.068 Kelem/s 35.332 Kelem/s]
change:
       time:   [-2.1399% -1.1603% -0.1824] (p = 0.02 < 0.05)
       thrpt:  [+0.1828% +1.1739% +2.1867]
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1504: No change in performance detected.
       time:   [38.542 ms 38.706 ms 38.889 ms]
       thrpt:  [25.714   B/s 25.836   B/s 25.946   B/s]
change:
       time:   [-0.8019% -0.1437% +0.5034] (p = 0.67 > 0.05)
       thrpt:  [-0.5009% +0.1440% +0.8084]
       No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
2 (2.00%) high mild
6 (6.00%) high severe
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1504: No change in performance detected.
       time:   [202.99 ms 203.47 ms 204.02 ms]
       thrpt:  [490.14 MiB/s 491.47 MiB/s 492.64 MiB/s]
change:
       time:   [-0.3128% +0.0221% +0.3565] (p = 0.90 > 0.05)
       thrpt:  [-0.3552% -0.0221% +0.3138]
       No change in performance detected.
Found 5 outliers among 100 measurements (5.00%)
1 (1.00%) high mild
4 (4.00%) high severe
decode 4096 bytes, mask ff: No change in performance detected.
       time:   [5.5763 µs 5.5850 µs 5.5939 µs]
       change: [-0.2152% +0.0040% +0.2470] (p = 0.98 > 0.05)
       No change in performance detected.
Found 5 outliers among 100 measurements (5.00%)
4 (4.00%) high mild
1 (1.00%) high severe
decode 1048576 bytes, mask ff: No change in performance detected.
       time:   [1.4271 ms 1.4311 ms 1.4372 ms]
       change: [-0.1075% +0.2766% +0.7720] (p = 0.23 > 0.05)
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high severe
decode 4096 bytes, mask 7f: No change in performance detected.
       time:   [8.4650 µs 8.4768 µs 8.4893 µs]
       change: [-0.2324% +0.0456% +0.3221] (p = 0.74 > 0.05)
       No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
3 (3.00%) high mild
1 (1.00%) high severe
decode 1048576 bytes, mask 7f: No change in performance detected.
       time:   [2.1773 ms 2.1818 ms 2.1874 ms]
       change: [-0.5134% -0.1047% +0.2900] (p = 0.62 > 0.05)
       No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
decode 4096 bytes, mask 3f: No change in performance detected.
       time:   [6.9032 µs 6.9140 µs 6.9254 µs]
       change: [-0.3095% -0.0267% +0.2410] (p = 0.85 > 0.05)
       No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
5 (5.00%) high mild
3 (3.00%) high severe
decode 1048576 bytes, mask 3f: No change in performance detected.
       time:   [1.7652 ms 1.7685 ms 1.7724 ms]
       change: [-0.2524% +0.0026% +0.2819] (p = 0.98 > 0.05)
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high severe
streams/simulated/1-streams/each-1000-bytes: No change in performance detected.
       time:   [129.68 ms 129.68 ms 129.68 ms]
       thrpt:  [7.5303 KiB/s 7.5305 KiB/s 7.5307 KiB/s]
change:
       time:   [-0.0023% +0.0015% +0.0052] (p = 0.46 > 0.05)
       thrpt:  [-0.0052% -0.0015% +0.0023]
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
streams/simulated/1000-streams/each-1-bytes: No change in performance detected.
       time:   [2.5361 s 2.5364 s 2.5367 s]
       thrpt:  [394.21   B/s 394.26   B/s 394.30   B/s]
change:
       time:   [-0.0220% -0.0059% +0.0102] (p = 0.48 > 0.05)
       thrpt:  [-0.0102% +0.0059% +0.0220]
       No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
4 (4.00%) high mild
streams/simulated/1000-streams/each-1000-bytes: No change in performance detected.
       time:   [6.5835 s 6.5909 s 6.5996 s]
       thrpt:  [147.97 KiB/s 148.17 KiB/s 148.34 KiB/s]
change:
       time:   [-0.1778% +0.0052% +0.1911] (p = 0.96 > 0.05)
       thrpt:  [-0.1907% -0.0052% +0.1781]
       No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
4 (4.00%) high severe
streams/walltime/1-streams/each-1000-bytes: No change in performance detected.
       time:   [586.66 µs 588.45 µs 590.55 µs]
       change: [-0.8296% -0.2135% +0.3625] (p = 0.50 > 0.05)
       No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
6 (6.00%) high severe
streams/walltime/1000-streams/each-1-bytes: Change within noise threshold.
       time:   [12.415 ms 12.433 ms 12.451 ms]
       change: [+0.0221% +0.2373% +0.4506] (p = 0.03 < 0.05)
       Change within noise threshold.
streams/walltime/1000-streams/each-1000-bytes: Change within noise threshold.
       time:   [45.128 ms 45.210 ms 45.329 ms]
       change: [+0.9418% +1.1548% +1.4658] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
2 (2.00%) high mild
1 (1.00%) high severe
coalesce_acked_from_zero 1+1 entries: No change in performance detected.
       time:   [92.813 ns 93.854 ns 95.679 ns]
       change: [-0.1248% +0.7778% +1.9582] (p = 0.18 > 0.05)
       No change in performance detected.
Found 14 outliers among 100 measurements (14.00%)
9 (9.00%) high mild
5 (5.00%) high severe
coalesce_acked_from_zero 3+1 entries: No change in performance detected.
       time:   [110.47 ns 110.82 ns 111.18 ns]
       change: [-0.3244% +0.1062% +0.5293] (p = 0.63 > 0.05)
       No change in performance detected.
Found 14 outliers among 100 measurements (14.00%)
2 (2.00%) high mild
12 (12.00%) high severe
coalesce_acked_from_zero 10+1 entries: No change in performance detected.
       time:   [110.01 ns 110.65 ns 111.47 ns]
       change: [-0.1652% +0.3048% +0.8085] (p = 0.26 > 0.05)
       No change in performance detected.
Found 10 outliers among 100 measurements (10.00%)
3 (3.00%) low mild
7 (7.00%) high severe
coalesce_acked_from_zero 1000+1 entries: No change in performance detected.
       time:   [94.346 ns 94.483 ns 94.630 ns]
       change: [-0.4063% +0.0605% +0.4596] (p = 0.80 > 0.05)
       No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
4 (4.00%) high mild
4 (4.00%) high severe
RxStreamOrderer::inbound_frame(): Change within noise threshold.
       time:   [107.86 ms 107.95 ms 108.03 ms]
       change: [-0.9959% -0.7995% -0.6440] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
sent::Packets::take_ranges: No change in performance detected.
       time:   [4.3918 µs 4.4779 µs 4.5497 µs]
       change: [-2.5511% +0.4449% +3.6039] (p = 0.78 > 0.05)
       No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
transfer/simulated/pacing-false/varying-seeds: No change in performance detected.
       time:   [23.941 s 23.941 s 23.941 s]
       thrpt:  [171.09 KiB/s 171.09 KiB/s 171.09 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-true/varying-seeds: No change in performance detected.
       time:   [23.676 s 23.676 s 23.676 s]
       thrpt:  [173.01 KiB/s 173.01 KiB/s 173.01 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-false/same-seed: No change in performance detected.
       time:   [23.941 s 23.941 s 23.941 s]
       thrpt:  [171.09 KiB/s 171.09 KiB/s 171.09 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-true/same-seed: No change in performance detected.
       time:   [23.676 s 23.676 s 23.676 s]
       thrpt:  [173.01 KiB/s 173.01 KiB/s 173.01 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/walltime/pacing-false/varying-seeds: Change within noise threshold.
       time:   [23.272 ms 23.301 ms 23.345 ms]
       change: [+1.9599% +2.1099% +2.3312] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 5 outliers among 100 measurements (5.00%)
1 (1.00%) low mild
3 (3.00%) high mild
1 (1.00%) high severe
transfer/walltime/pacing-true/varying-seeds: Change within noise threshold.
       time:   [23.508 ms 23.537 ms 23.580 ms]
       change: [+1.2549% +1.4040% +1.5998] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
2 (2.00%) high mild
1 (1.00%) high severe
transfer/walltime/pacing-false/same-seed: Change within noise threshold.
       time:   [23.229 ms 23.258 ms 23.302 ms]
       change: [+1.1809% +1.3314% +1.5170] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
transfer/walltime/pacing-true/same-seed: Change within noise threshold.
       time:   [23.990 ms 24.011 ms 24.037 ms]
       change: [+2.3453% +2.4665% +2.5992] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high severe

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

@larseggert
Copy link
Copy Markdown
Collaborator

So, I think we should land it, but I have not yet sent the email to IANA. I'm drafting it right now.

So we should wait with landing this until we have codepoints? Or land it and then change them in a follow-on PR?

@martinthomson
Copy link
Copy Markdown
Member Author

So we should wait with landing this until we have codepoints? Or land it and then change them in a follow-on PR?

Given how QUIC registries work (registrant suggests a codepoint), I think we're good to land. The risk of a codepoint change is low.

@larseggert larseggert added this pull request to the merge queue Mar 13, 2026
Merged via the queue into mozilla:main with commit 4c45dc6 Mar 13, 2026
196 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocked Blocked on something else

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants