Skip to content

Fix QUIC echo benchmark: remove --verbose, fix duration overlap and arg serialization#847

Merged
ProjectsByJackHe merged 13 commits intomainfrom
fix/quic-echo-duration-and-args
May 7, 2026
Merged

Fix QUIC echo benchmark: remove --verbose, fix duration overlap and arg serialization#847
ProjectsByJackHe merged 13 commits intomainfrom
fix/quic-echo-duration-and-args

Conversation

@Alan-Jowett
Copy link
Copy Markdown
Member

Summary

Three bugs caused QUIC echo benchmarks over the real network to report ~9.4K RPS instead of the expected ~3.35M RPS (a 356x undercount).

Bugs Fixed

1. --verbose\ I/O backpressure (224x impact)

The script hardcoded --verbose\ on both client and server. This flag logs per-datagram events (send state changes, datagram received/echoed), not just periodic stats. At high RPS this generates tens of thousands of log lines per second. On the server side, this output flows through PS remoting CLIXML serialization, creating severe I/O backpressure that throttled throughput from 3.35M to ~12K RPS. Periodic \RPS=\ stats print regardless of --verbose.

2. Server duration overlap (halved effective measurement)

Both server and client received the same --duration\ value, but the script waits 5 seconds for server startup before launching the client. With \duration=10, the server exits at T+10 while the client runs T+5 to T+15, yielding 0 RPS for the last 5 seconds. Fix: give the server extra duration buffer (startup delay + 5s margin).

3. PS remoting argument serialization

\Invoke-ToolInSession\ passed options via -ArgumentList\ with (,)\ wrapping, but CLIXML serialization still collapsed the array into a single string token. The remote tool received one concatenated argument instead of individual tokens. Fix: serialize options as JSON before passing through -ArgumentList\ and deserialize on the remote side.

Results

Metric Before Fix After Fix Loopback VM
RPS 9,418 3,352,414 2,107,563
Avg Latency 109.40 ms 0.57 ms 0.92 ms
Errors 0 0 0

The network result is now 59% faster than the loopback VM benchmark (lab machines have more resources).

Files Changed

  • .github/scripts/performance_utilities.psm1\ — JSON-based arg serialization in \Invoke-ToolInSession\
  • .github/scripts/run-quic-echo-test.ps1\ — remove --verbose, add server duration buffer
  • .github/scripts/run-echo-test.ps1\ — add server duration buffer (same overlap bug)

Validation

Alan Jowett and others added 13 commits May 6, 2026 11:57
Point the network-traffic-performance workflow at the merged WinQuicEcho startup ramp fix so quicEcho runs use the new client startup behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pass the WinQuicEcho repository to the reusable build workflow so the pinned SHA is checked out from the correct repository before building the quicEcho artifact.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Provision msquic-km server certificates in LocalMachine\My instead of CurrentUser\My, clean them up from the matching store, and fail fast when the remote echo_server exits during startup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep remote tool arguments as real token arrays through Invoke-Command and Start-Job instead of collapsing them into a single string token. This lets the remote WinQuicEcho server receive the intended backend, port, and cert-hash arguments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Treat deserialized PowerShell enumerable token lists such as System.Collections.ArrayList as real argv arrays in the remote invocation helper, instead of collapsing them into a single string token.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two bugs caused QUIC echo benchmarks over real networks to report
dramatically lower throughput than expected:

1. Server exits before client finishes: Both server and client received
   the same --duration value, but the script waits 5 seconds for server
   startup before launching the client. With duration=10, the server
   exits at T+10 while the client runs T+5 to T+15, yielding 0 RPS
   for the last 5 seconds. Fix: give the server extra duration buffer
   (startup delay + 5s margin).

2. PS remoting flattens argument arrays: Invoke-ToolInSession passed
   options via -ArgumentList with (,\) wrapping, but CLIXML
   serialization still collapsed the array into a single string token.
   The remote tool received one concatenated argument instead of
   individual tokens. Fix: serialize options as JSON before passing
   through -ArgumentList and deserialize on the remote side.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The --verbose flag logs per-datagram events (send state changes,
datagram received, datagram echoed) rather than just periodic stats.
At high RPS this generates tens of thousands of log lines per second,
causing severe I/O backpressure — especially on the server side where
output flows through PS remoting CLIXML serialization. Periodic RPS
stats print regardless of --verbose.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add PEM cert generation for non-Schannel backends (picoquic, ngtcp2)
- Update Run-SendTest/Run-RecvTest to use --cert-file/--key-file for
  OpenSSL-based backends instead of --cert-hash
- Update workflow to build WinQuicEcho with picoquic enabled
- Pin WinQuicEcho ref to commit with build_picoquic support

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Alan-Jowett Alan-Jowett force-pushed the fix/quic-echo-duration-and-args branch from a0c5b76 to eec1cc6 Compare May 7, 2026 00:27
@ProjectsByJackHe
Copy link
Copy Markdown
Collaborator

LGTM! Let's merge it

@ProjectsByJackHe ProjectsByJackHe merged commit 0c8e3ea into main May 7, 2026
6 of 7 checks passed
@ProjectsByJackHe ProjectsByJackHe deleted the fix/quic-echo-duration-and-args branch May 7, 2026 00:28
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.

2 participants