Skip to content

feat(cc): put ABE (RFC 8511) behind a pref. - #4090

Merged
omansfeld merged 1 commit into
mozilla:mainfrom
omansfeld:ecn-abe-pref
Oct 19, 2026
Merged

omansfeld merged 1 commit into
mozilla:mainfrom
omansfeld:ecn-abe-pref

Conversation

@omansfeld

Copy link
Copy Markdown
Collaborator

This will enable us to do experiments studying ABE performance on Firefox.

See https://bugzilla.mozilla.org/show_bug.cgi?id=2062270 for more info on my planned ECN performance study.

@omansfeld omansfeld self-assigned this Oct 16, 2026
Copilot AI balanced review requested due to automatic review settings October 16, 2026 17:11

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.

🟢 Approval recommended

The setting is consistently wired, preserves existing behavior by default, and has focused regression coverage; tests were not executed.

0 open findings

What changed in this PR

Makes Alternative Backoff with ECN (ABE) configurable for CUBIC, supporting Firefox performance experiments while preserving the enabled default.

Changes:

  • Adds an ABE connection setting and --no-abe CLI flag.
  • Propagates the setting to all CUBIC slow-start variants.
  • Tests configuration toggling and congestion-window reductions.
File Description
neqo-transport/​src/​sender.rs Passes the ABE setting to CUBIC.
neqo-transport/​src/​connection/​params.rs Adds the setting, default, and toggle test.
neqo-transport/​src/​cc/​tests/​mod.rs Supports configurable CUBIC test instances.
neqo-transport/​src/​cc/​tests/​cubic.rs Tests backoff behavior with ABE disabled.
neqo-transport/​src/​cc/​cubic.rs Gates alternative ECN backoff on the setting.
neqo-bin/​src/​lib.rs Adds and wires --no-abe.

🧠 Review effort: Balanced


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

@codecov

codecov Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.99%. Comparing base (98041a4) to head (7cd4a09).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4090      +/-   ##
==========================================
- Coverage   97.14%   96.99%   -0.16%     
==========================================
  Files         113      118       +5     
  Lines       41500    41869     +369     
  Branches    41500    41869     +369     
==========================================
+ Hits        40314    40609     +295     
- Misses       1172     1236      +64     
- Partials       14       24      +10     
Flag Coverage Δ
freebsd 94.57% <100.00%> (-0.14%) ⬇️
linux 97.19% <100.00%> (-0.02%) ⬇️
macos 95.37% <100.00%> (+0.01%) ⬆️
windows 95.45% <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.38% <ø> (ø)
neqo-qpack 97.10% <ø> (ø)
neqo-transport 97.98% <100.00%> (+<0.01%) ⬆️
neqo-udp 95.37% <ø> (ø)
mtu 89.13% <ø> (ø)

@codspeed

codspeed Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will regress 2 benchmarks

⚡ 5 improved benchmarks
❌ 2 regressed benchmarks
✅ 94 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Simulation simulated/pacing-false/varying-seeds 73.2 ms 76.4 ms -4.23%
❌ WallTime neqo-neqo-cubic 20.3 ms 21 ms -3.02%
⚡ WallTime neqo-s2n 50.5 ms 48.9 ms +3.15%
⚡ WallTime walltime/pacing-true/same-seed 2 ms 2 ms +2.29%
⚡ WallTime 1-conn/1-1b-resp (aka. HPS) 3 ms 2.9 ms +2.17%
⚡ WallTime walltime/pacing-true/varying-seeds 2 ms 2 ms +2.15%
⚡ WallTime walltime/1-streams/each-1000-bytes 130.9 µs 128.2 µs +2.14%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing omansfeld:ecn-abe-pref (7cd4a09) with main (ad7d629)

Open in CodSpeed

@larseggert

Copy link
Copy Markdown
Collaborator

Is ABE not orthogonal to whether CUBIC or Reno are used?

@omansfeld

Copy link
Copy Markdown
Collaborator Author

Is ABE not orthogonal to whether CUBIC or Reno are used?

It is in theory, but we currently only implement it for cubic.

That’s why I put the pref on cubic instead of on the congestion controller. The diff would be bigger if it was a layer above because of changing function calls etc.

In general I don’t think it is worth it to implement ABE in Reno right now. We don’t use Reno and the constant needs to be separately tuned from cubic.

@larseggert

Copy link
Copy Markdown
Collaborator

I wonder if there is any point in keeping the Reno code around...

@omansfeld

Copy link
Copy Markdown
Collaborator Author

I wonder if there is any point in keeping the Reno code around...

I think it can be useful as a barebones RFC 9002/new reno reference. But right now we have some performance optimizations (e.g. spurious recovery) active for both, and some only for Cubic. So I agree that state is not that useful.

If we decided to rip out everything but Cubic and also that we won't be doing any non-loss cc anytime soon (thus no need for the current CongestionController --> ClassicCongestionControl abstraction) then there is a lot of code complexity that could be reduced in the cc code.

I'll open an issue to discuss/track this.

This will enable us to do experiments studying ABE performance on
Firefox.

See https://bugzilla.mozilla.org/show_bug.cgi?id=2062270 for more info
on my planned ECN performance study.
@omansfeld

Copy link
Copy Markdown
Collaborator Author

I'll open an issue to discuss/track this.

There is #3453. I added this discussion to it.

@github-actions

Copy link
Copy Markdown
Contributor

Client/server transfer results

Performance differences relative to ad7d629.

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 70.0 ± 0.4 69.3 – 71.0 70.0 ± 0.4 457.1 ± 2.4 💔 +1.4 (+2.0%)
neqo-google-cubic 227.0 ± 36.3 176.2 – 448.4 218.8 ± 26.3 140.9 ± 22.5 💚 -14.1 (-6.1%)
neqo-neqo-newreno 19.8 ± 0.1 19.5 – 20.2 19.8 ± 0.1 1616.3 ± 11.8 💔 +0.2 (+1.1%)

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 132.0 ± 0.5 130.9 – 133.2 132.0 ± 0.5 242.4 ± 0.9
google-neqo-cubic 70.0 ± 0.4 69.3 – 71.0 70.0 ± 0.4 457.1 ± 2.4 💔 +1.4 (+2.0%)
neqo-google-cubic 227.0 ± 36.3 176.2 – 448.4 218.8 ± 26.3 140.9 ± 22.5 💚 -14.1 (-6.1%)
neqo-neqo-cubic 19.9 ± 0.1 19.6 – 20.2 19.9 ± 0.2 1604.6 ± 11.2 +0.0 (+0.0%)
neqo-neqo-cubic-nopacing 19.1 ± 0.2 18.7 – 19.9 19.1 ± 0.2 1672.1 ± 15.3 +0.0 (+0.1%)
neqo-neqo-newreno 19.8 ± 0.1 19.5 – 20.2 19.8 ± 0.1 1616.3 ± 11.8 💔 +0.2 (+1.1%)
neqo-neqo-newreno-nopacing 19.6 ± 0.2 19.2 – 20.0 19.6 ± 0.1 1636.4 ± 13.9 -0.0 (-0.0%)
neqo-quiche-cubic 29.2 ± 0.3 28.6 – 29.9 29.2 ± 0.2 1095.1 ± 9.5 +0.1 (+0.3%)
neqo-s2n-cubic 38.4 ± 0.2 38.0 – 38.9 38.4 ± 0.2 834.0 ± 4.2 +0.0 (+0.1%)
quiche-neqo-cubic ⚠️ 31.3 ± 2.7 30.0 – 58.2 31.0 ± 0.3 1021.4 ± 89.4 -0.1 (-0.4%)
quiche-quiche 35.4 ± 0.3 34.7 – 35.9 35.4 ± 0.2 904.0 ± 6.4
s2n-neqo-cubic 118.0 ± 0.5 116.8 – 119.4 117.9 ± 0.3 271.3 ± 1.2 +0.0 (+0.0%)
s2n-s2n ⚠️ 168.8 ± 25.0 138.3 – 258.2 161.7 ± 1.3 189.6 ± 28.1

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 ad7d629.

All results
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1500
       time:   [50.306 ms 50.329 ms 50.354 ms]
       thrpt:  [1.9394 GiB/s 1.9403 GiB/s 1.9413 GiB/s]
Found 3 outliers among 100 measurements (3.00%)
1 (1.00%) low mild
1 (1.00%) high mild
1 (1.00%) high severe
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1500
       time:   [52.037 ms 52.066 ms 52.096 ms]
       thrpt:  [1.8746 GiB/s 1.8756 GiB/s 1.8767 GiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1500
       time:   [2.9774 ms 2.9795 ms 2.9815 ms]
       thrpt:  [335.40   B/s 335.63   B/s 335.86   B/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1500
       time:   [67.421 ms 67.758 ms 68.105 ms]
       thrpt:  [146.83 Kelem/s 147.58 Kelem/s 148.32 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:   [10.632 ms 10.635 ms 10.638 ms]
       thrpt:  [376.03 MiB/s 376.13 MiB/s 376.23 MiB/s]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
streams-flow-controlled/walltime/10-streams/each-1048576-bytes
       time:   [28.260 ms 28.270 ms 28.280 ms]
       thrpt:  [353.60 MiB/s 353.73 MiB/s 353.86 MiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
streams/walltime/1-streams/each-1000-bytes
       time:   [132.29 µs 132.85 µs 133.55 µs]
       thrpt:  [7.1407 MiB/s 7.1786 MiB/s 7.2088 MiB/s]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
streams/walltime/1000-streams/each-1-bytes
       time:   [3.7571 ms 3.7685 ms 3.7797 ms]
       thrpt:  [258.37 KiB/s 259.14 KiB/s 259.93 KiB/s]
streams/walltime/1000-streams/each-1000-bytes
       time:   [12.529 ms 12.536 ms 12.544 ms]
       thrpt:  [76.029 MiB/s 76.074 MiB/s 76.120 MiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) low mild
transfer/walltime/pacing-false/same-seed
       time:   [1.9996 ms 2.0006 ms 2.0018 ms]
       thrpt:  [1.9514 GiB/s 1.9526 GiB/s 1.9535 GiB/s]
transfer/walltime/pacing-false/varying-seeds
       time:   [2.0204 ms 2.0213 ms 2.0224 ms]
       thrpt:  [1.9315 GiB/s 1.9326 GiB/s 1.9334 GiB/s]
transfer/walltime/pacing-true/same-seed
       time:   [2.0787 ms 2.0813 ms 2.0844 ms]
       thrpt:  [1.8740 GiB/s 1.8768 GiB/s 1.8791 GiB/s]
transfer/walltime/pacing-true/varying-seeds
       time:   [2.0170 ms 2.0181 ms 2.0193 ms]
       thrpt:  [1.9344 GiB/s 1.9356 GiB/s 1.9367 GiB/s]

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.11 3.19 +2.6%
streams/walltime/1000-streams/each-1-bytes 3.27 3.31 +1.3%
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1500 3.17 3.14 -1.1%
streams/walltime/1000-streams/each-1000-bytes 3.00 3.02 +1.0%
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1500 3.18 3.21 +0.9%
streams-flow-controlled/walltime/1-streams/each-4194304-bytes 3.04 3.01 -0.8%
transfer/walltime/pacing-false/varying-seeds 2.86 2.85 -0.5%
transfer/walltime/pacing-false/same-seed 2.86 2.88 +0.5%
transfer/walltime/pacing-true/same-seed 2.86 2.87 +0.3%
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1500 3.20 3.21 +0.3%
streams/walltime/1-streams/each-1000-bytes 2.53 2.53 +0.2%
transfer/walltime/pacing-true/varying-seeds 2.86 2.86 +0.1%
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1500 2.24 2.24 -0.1%
Profiles for profiler.firefox.com (64)

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

@github-actions

Copy link
Copy Markdown
Contributor

Failed Interop Tests

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

neqo-pr as clientneqo-pr as server
neqo-pr vs. go-x-net: BP BA
neqo-pr vs. haproxy: BP BA
neqo-pr vs. kwik: 🚀S ⚠️LR Z ⚠️U L1 🚀L2 C1 🚀BP ⚠️C2 6 BA
neqo-pr vs. linuxquic: ⚠️L1
neqo-pr vs. lsquic: L1 C1
neqo-pr vs. msquic: Z A L1 C1
neqo-pr vs. mvfst: A ⚠️L1 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
neqo-pr vs. quic-go: A
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
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: 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

@omansfeld
omansfeld added this pull request to the merge queue Oct 19, 2026
Merged via the queue into mozilla:main with commit d245301 Oct 19, 2026
304 of 308 checks passed
@omansfeld
omansfeld deleted the ecn-abe-pref branch October 19, 2026 11:01
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.

3 participants