Skip to content
github-actions[bot] edited this page Sep 16, 2026 · 210 revisions

Performance

Throughput and footprint of Titanium as a reverse / edge proxy and as a decrypting (MITM) proxy, measured on the same harness against YARP, nginx, HAProxy, and Envoy where each OS can run them.

RPS is requests per second (gRPC tables use RPC/s). Numbers are Release builds on matched GitHub-hosted runners: Windows and Linux at 4 vCPU / 16 GiB, macOS at macos-15-intel 4-core / 14 GB. Read within one table — absolute RPS is not comparable across operating systems. Not possible means that product cannot run that path on that OS; Not measured means the path exists but no published number yet.

For pooling knobs and certificate first-visit tuning, see Performance and pooling. Laptop cool A/B tables (not publishable) live on Performance Local Lab.

Why this comparison is fair

  • Same load generator, same origin process, and the same warmup / measure windows (2s / 8s) with the same concurrency ramp (8, 16, 32, 64).
  • Every reverse arm is three OS processes: load generator + origin + proxy. Origin-direct omits the proxy; peers are never in-process with the client.
  • Same runner class per table (windows-latest / ubuntu-latest / macos-15-intel). Laptop numbers are never mixed into these tables.
  • Peers use equivalent TLS/ALPN and streaming-friendly settings on the same loopback shape. HAProxy and Envoy are Linux/macOS only — Not possible on Windows, so their columns are omitted there.
  • MITM (HTTPS decryption with forged certificates) is Titanium-only; peers cannot MITM. Those tables show Titanium MITM overhead versus its own reverse path on the same wires.
  • Tiny keep-alive GET (~56-byte JSON) is the industry RPS shape (same class as wrk / TechEmpower). It is also real for small JSON APIs and health checks.
  • Same-protocol H2↔H2 / H3↔H3 on that shape is Titanium’s best case: with interception off, Titanium copies frames instead of decoding and re-encoding headers (peers do a full HTTP decode). Medals there are not the typical reverse-proxy job.
  • Typical reverse is H1 TLS→H1 or H2→H1 (~1.1× YARP on tiny GET). With larger bodies, see Heavier reverse: at 64 KiB H2 TLS→H2 TLS, Titanium is behind YARP (~0.69–0.76×).

How to read the tables

  • Bold RPS is sustain (last concurrency that still met error/latency SLOs). When peak differs, it appears in the same cell as <sub>(peak N · …)</sub> with RSS/CPU. When sustain equals peak, peak is omitted.
  • 🥇 = best among Titanium / nginx / YARP on Reverse rows (highest RPS; on a tie, lower memory then lower CPU%). Gold medals are per cell on tiny GET — an H2↔H2 gold is that frame-copy best case, not “Titanium is 1.7× on all reverse.” For larger-body H2→H2, see the heavier tables.
  • MITM tables are Titanium-only. Lite÷Reverse / Full÷Reverse = Titanium MITM sustain ÷ Titanium reverse sustain on the same Client×Origin pair — the overhead of decrypting and intercepting versus bare reverse, not versus nginx or YARP.
  • Not possible = cannot do that path. Not measured = path exists but no published number yet. When every row would be Not possible for a peer, that column is omitted and a note above the table explains why.

Contents

Measurement environment

All three OS use the 4-core-class public-repo GitHub-hosted runners: Windows / Linux at 4 vCPU / 16 GiB / 14 GB SSD, macOS at macos-15-intel 4-core / 14 GB (not macos-latest). Same harness knobs: warmup 2s / measure 8s; concurrency 8, 16, 32, 64; median of 3 repeats. Prefer Titanium÷YARP / Titanium÷nginx ratios over absolute RPS.

Laptop High-perf / cool-paired Windows numbers live on Performance Local Lab. Do not mix those absolutes into the tables below.

Windows (GitHub-hosted windows-latest)

OS Windows Server (GitHub-hosted windows-latest)
CPU 4 logical processors
RAM 16 GiB
Runtime .NET 10.0.x
nginx nginx/Windows 1.31.3 (same-OS only; no QUIC)
HAProxy Not possible on Windows (no official port)
Envoy Not possible on Windows (upstream discontinued Windows builds)
YARP Yarp.ReverseProxy 2.3.0
Harness RpsLoadProbe Release; median of 3 repeats

Linux (GitHub-hosted ubuntu-latest)

OS Ubuntu 24.04.x LTS
CPU 4 logical processors (AMD EPYC; runners this pass were 7763 / 9V74)
RAM 16 GiB
Runtime .NET 10.0.11
nginx nginx/1.31.4 (nginx.org mainline, --with-http_v3_module)
HAProxy HAProxy 3.2.23 built with USE_QUIC (GHA; Ubuntu distro 2.8 is not QUIC-capable)
Envoy pinned GitHub release static binary 1.36.7 (HTTP/3 compiled in)
YARP Yarp.ReverseProxy 2.3.0
Harness RpsLoadProbe Release; median of 3 repeats where noted

macOS (GitHub-hosted macos-15-intel)

OS macOS 15 (GitHub-hosted macos-15-intel, Intel x86_64)
CPU 4 logical processors
RAM 14 GB
Runtime .NET 10.0.x
nginx Homebrew nginx with --with-http_v3_module (workflow fails if missing)
HAProxy Homebrew haproxy with USE_QUIC (workflow fails if missing; 3.2.23 osx source fallback)
Envoy Homebrew bottle when present; else pinned darwin-amd64 1.36.7 (official GitHub assets are Linux-only). HTTP/3 compiled in.
MsQuic Homebrew libmsquic + openssl@3 on DYLD_LIBRARY_PATH / DYLD_FALLBACK_LIBRARY_PATH (QuicListener.IsSupported)
YARP Yarp.ReverseProxy 2.3.0
Harness RpsLoadProbe Release; median of 3 repeats where noted

Do not use macos-latest (Apple Silicon, 3-core / 7 GB) for publishable saturation numbers.

Saturation control

Calibration for the shared 4 vCPU loopback shape: how close client + origin are to saturated before ranking reverse peers. Tiny keep-alive GET. Median of 3 repeats @ 8bfa7852 — 35092854050. Warmup 2s / measure 8s; concurrency 8, 16, 32, 64. Block A % of origin-HttpClient uses median peak RPS. Blocks B/C use peer÷YARP / ÷nginx on median peak (not % of H1 origin). RPS cells embed median RSS / CPU for the proxy child plus its full descendant tree (serve-proxy → nginx master → workers); origin-direct samples the origin child. Product matrices below use matched dotnet-httpclient only (not bombardier).

Block A — H1 plain

Arm Generator Notes
origin-direct dotnet-httpclient No proxy — origin ceiling under the same client used for publishable ratios
origin-direct-bombardier bombardier External client check (CI installs bombardier)
bare-reverse-http1 dotnet-httpclient Thin C# H1 reverse (BareHttp1ReverseProxy) — .NET runtime / loopback ceiling for a three-process reverse hop; not a product peer
nginx-reverse-http1 / yarp-reverse-http1 / twp-reverse-http1 dotnet-httpclient Product peers (medals among these three only)

Windows (windows-latest)

Arm Generator RPS % of origin-HttpClient
origin-direct dotnet-httpclient 81,217
(55 MiB / 45.3% CPU)
100.0%
origin-direct-bombardier bombardier 61,721
(56 MiB / 25.1% CPU)
76.0%
bare-reverse-http1 dotnet-httpclient 39,529
(56 MiB / 44.1% CPU)
48.7%
nginx-reverse-http1 dotnet-httpclient 24,677
(125 MiB / 24.9% CPU)
30.4%
yarp-reverse-http1 dotnet-httpclient 34,602
(90 MiB / 49.2% CPU)
42.6%
twp-reverse-http1 dotnet-httpclient 🥇 40,685
(76 MiB / 50.9% CPU)
50.1%

Linux (ubuntu-latest)

Arm Generator RPS % of origin-HttpClient
origin-direct dotnet-httpclient 131,605
(81 MiB / 45.0% CPU)
100.0%
origin-direct-bombardier bombardier 81,228
(80 MiB / 38.3% CPU)
61.7%
bare-reverse-http1 dotnet-httpclient 58,771
(70 MiB / 46.0% CPU)
44.7%
nginx-reverse-http1 dotnet-httpclient 🥇 74,446
(77 MiB / 39.5% CPU)
56.6%
yarp-reverse-http1 dotnet-httpclient 55,568
(115 MiB / 48.0% CPU)
42.2%
twp-reverse-http1 dotnet-httpclient 63,570
(92 MiB / 50.3% CPU)
48.3%

Reverse peers are about 50–46% of the origin-direct HttpClient peak on this runner class (Win TWP 50.0%, Lin TWP 45.6%). Prefer the % column over absolute RPS across runs. Bare and origin-direct are controls (not medal peers).

Block B — H2 TLS→H1

Peer ratios (÷YARP / ÷nginx) on median peak; RPS cells embed (MiB / CPU%).

Windows (windows-latest)

Arm Generator RPS ÷YARP ÷nginx
nginx-reverse-http2 dotnet-httpclient 14,697
(141 MiB / 24.4% CPU)
0.32× 1.00×
yarp-reverse-http2 dotnet-httpclient 45,876
(96 MiB / 50.8% CPU)
1.00× 3.12×
twp-reverse-http2-cleartext dotnet-httpclient 🥇 51,822
(103 MiB / 52.9% CPU)
1.13× 3.53×

Linux (ubuntu-latest)

Arm Generator RPS ÷YARP ÷nginx
nginx-reverse-http2 dotnet-httpclient 29,423
(102 MiB / 18.9% CPU)
0.46× 1.00×
yarp-reverse-http2 dotnet-httpclient 64,174
(123 MiB / 46.6% CPU)
1.00× 2.18×
twp-reverse-http2-cleartext dotnet-httpclient 🥇 66,465
(123 MiB / 51.4% CPU)
1.04× 2.26×

Block C — H3→H1

Same layout as Block B. Requires QuicListener. nginx needs http_v3_module (Windows nginx has no QUIC). HAProxy needs USE_QUIC (GHA Linux/macOS require it). Envoy 1.20+ includes HTTP/3.

Windows (windows-latest)

Arm Generator RPS ÷YARP ÷nginx
nginx-reverse-http3-cleartext dotnet-httpclient Not possible (no QUIC) — —
yarp-reverse-http3-cleartext dotnet-httpclient 24,601
(148 MiB / 50.5% CPU)
1.00× —
twp-reverse-http3-cleartext dotnet-httpclient 🥇 24,701
(117 MiB / 43.9% CPU)
1.00× —

Linux (ubuntu-latest)

Arm Generator RPS ÷YARP ÷nginx
nginx-reverse-http3-cleartext dotnet-httpclient 0
(peak 38,114 · 113 MiB / 20.9% CPU)
0.96× 1.00×
yarp-reverse-http3-cleartext dotnet-httpclient 39,807
(215 MiB / 48.7% CPU)
1.00× 1.04×
twp-reverse-http3-cleartext dotnet-httpclient 🥇 44,892
(177 MiB / 53.4% CPU)
1.13× 1.18×

Windows — Titanium vs nginx vs HAProxy vs Envoy vs YARP

Client / origin: HTTP version and whether TLS is used (plain = cleartext, TLS = encrypted, QUIC = HTTP/3).

Reverse

Median of 3 repeats on windows-latest (4 vCPU / 16 GiB). Bare reverse 5×5 @ 8bfa7852 — compare-product 35092827644. Warmup 2s / measure 8s; concurrency 8, 16, 32, 64. Prefer TWP÷peer ratios over absolute RPS. RPS cells include median RSS / CPU at the peak-RPS step as <br><sub>(MiB / CPU%)</sub>. nginx terminate peers use keepalive 256 + streaming buffers. HAProxy / Envoy are Linux-only peers (no official Windows port). Laptop High-perf / cool-paired numbers stay on the local lab. Product 5×5 is ~56-byte JSON keep-alive GET; H2/H3 same-protocol cells are mostly header work with a tiny body (Titanium best case) — see Why this comparison is fair.

Load generators: Reverse inbound H3 arms use dotnet-httpclient (http_version=3.0, RequestVersionExact). nginx/Windows is same-OS only (no QUIC). HAProxy/Envoy are Linux-only terminate peers.

Client Origin TWP nginx YARP
HTTP/1 · plain HTTP/1 · plain 🥇 31,552
(75 MiB / 51.1% CPU)
19,301
(125 MiB / 25% CPU)
26,979
(90 MiB / 48.1% CPU)
HTTP/1 · plain HTTP/1 · TLS 🥇 20,447
(90 MiB / 52.6% CPU)
8,419
(136 MiB / 24.6% CPU)
18,937
(100 MiB / 48.3% CPU)
HTTP/1 · plain HTTP/2 · plain 🥇 36,987
(108 MiB / 45.2% CPU)
Not possible (no H2 upstream) 32,831
(93 MiB / 46.7% CPU)
HTTP/1 · plain HTTP/2 · TLS 🥇 39,580
(117 MiB / 47.3% CPU)
Not possible (no H2 upstream) 36,173
(98 MiB / 48.9% CPU)
HTTP/1 · plain HTTP/3 · QUIC 11,519
(104 MiB / 35% CPU)
Not possible (no H3 upstream) 🥇 18,177
(118 MiB / 49.9% CPU)
HTTP/1 · TLS HTTP/1 · plain 🥇 20,182
(86 MiB / 53.9% CPU)
8,534
(142 MiB / 24.7% CPU)
18,049
(102 MiB / 49.4% CPU)
HTTP/1 · TLS HTTP/1 · TLS 🥇 23,518
(84 MiB / 47.8% CPU)
9,376
(144 MiB / 24.8% CPU)
20,816
(102 MiB / 51.2% CPU)
HTTP/1 · TLS HTTP/2 · plain 🥇 27,742
(115 MiB / 46% CPU)
Not possible (no H2 upstream) 26,111
(108 MiB / 49.6% CPU)
HTTP/1 · TLS HTTP/2 · TLS 🥇 25,046
(119 MiB / 47% CPU)
Not possible (no H2 upstream) 24,356
(108 MiB / 47.4% CPU)
HTTP/1 · TLS HTTP/3 · QUIC 🥇 19,385
(111 MiB / 50.9% CPU)
Not possible (no H3 upstream) 18,399
(129 MiB / 49.7% CPU)
HTTP/2 · plain HTTP/1 · plain 🥇 34,785
(95 MiB / 53.6% CPU)
9,225
(127 MiB / 24.8% CPU)
31,535
(84 MiB / 53.4% CPU)
HTTP/2 · plain HTTP/1 · TLS 🥇 29,745
(98 MiB / 49% CPU)
6,559
(138 MiB / 24.9% CPU)
27,120
(96 MiB / 54% CPU)
HTTP/2 · plain HTTP/2 · plain 🥇 114,586
(59 MiB / 27.4% CPU)
Not possible (no H2 upstream) 69,424
(94 MiB / 48.1% CPU)
HTTP/2 · plain HTTP/2 · TLS 🥇 86,454
(65 MiB / 28.5% CPU)
Not possible (no H2 upstream) 55,488
(99 MiB / 46.8% CPU)
HTTP/2 · plain HTTP/3 · QUIC 🥇 31,645
(121 MiB / 52.4% CPU)
Not possible (no H3 upstream) 28,884
(120 MiB / 52.8% CPU)
HTTP/2 · TLS HTTP/1 · plain 🥇 39,258
(103 MiB / 51.6% CPU)
11,247
(141 MiB / 24.3% CPU)
35,070
(94 MiB / 49% CPU)
HTTP/2 · TLS HTTP/1 · TLS 🥇 29,467
(106 MiB / 54% CPU)
6,379
(145 MiB / 24.6% CPU)
25,223
(97 MiB / 51.8% CPU)
HTTP/2 · TLS HTTP/2 · plain 🥇 101,094
(78 MiB / 26.5% CPU)
Not possible (no H2 upstream) 54,554
(99 MiB / 50.8% CPU)
HTTP/2 · TLS HTTP/2 · TLS 🥇 88,782
(75 MiB / 28.5% CPU)
Not possible (no H2 upstream) 53,218
(103 MiB / 48.9% CPU)
HTTP/2 · TLS HTTP/3 · QUIC 🥇 30,154
(129 MiB / 54.2% CPU)
Not possible (no H3 upstream) 26,201
(123 MiB / 51.9% CPU)
HTTP/3 · QUIC HTTP/1 · plain 🥇 14,399
(101 MiB / 45.8% CPU)
Not possible (no QUIC) 14,330
(142 MiB / 51.1% CPU)
HTTP/3 · QUIC HTTP/1 · TLS 🥇 17,592
(116 MiB / 44.1% CPU)
Not possible (no QUIC) 15,607
(147 MiB / 48.8% CPU)
HTTP/3 · QUIC HTTP/2 · plain 🥇 34,116
(136 MiB / 47.7% CPU)
Not possible (no H2 upstream) 23,176
(151 MiB / 47.4% CPU)
HTTP/3 · QUIC HTTP/2 · TLS 🥇 31,135
(137 MiB / 47.1% CPU)
Not possible (no H2 upstream) 21,466
(150 MiB / 48.8% CPU)
HTTP/3 · QUIC HTTP/3 · QUIC 17,411
(119 MiB / 41.5% CPU)
Not possible (no H3 upstream) 🥇 18,619
(163 MiB / 48.3% CPU)

MITM (TWP only)

Same Client×Origin wires with interception on (compare-product 35092827644). Lite = no-op handlers (unchanged-lite finish). Full = append-only header mutation (harness: one probe header each way; product: generic append-only relay via MitmCompressedRelayHelper). nginx/HAProxy/Envoy/YARP cannot MITM. Lite÷Reverse / Full÷Reverse vs bare reverse (same job / comparison-group shard). Completion gate: Lite ≥ 0.50× and Full ≥ 0.50× reverse sustain @ c=64 (median of 3 GHA runs); reverse TWP÷YARP ≥ 0.75× (no terminate-peer gate).

v1 append-only relay (2026-08-27): Pre-fix H2→H2 Full÷Reverse was 0.13–0.16× (32960766249). Post-fix @ df172718: H2 plain→H2 plain Full 0.77–0.79×, H3→H1 Full 0.91–0.93×, all MITM arms ≥ 0.70× on median of 33041445371, 33055267086, 33055272140.

v2 drop-only + non-unique append (2026-08-27): MitmStaticRebuildHelper rebuilds static HPACK/QPACK after 1–4 unique header drops; trailing non-unique appends stay on compressed relay. @ 8bfa7852: all MITM arms ≥ 0.70× on GHA median (33087088466, 33087091622, 33105885748 Linux; 33087085235, 33087088466, 33087091622 Windows). H2 plain→H2 plain Full 0.77–0.79× (Win) / 0.78× (Lin).

Client Origin Lite sustain Full sustain Lite÷Reverse Full÷Reverse
HTTP/1 · plain HTTP/1 · plain 30,988
(80 MiB / 46.4% CPU)
30,492
(82 MiB / 48.2% CPU)
0.98× 0.97×
HTTP/1 · plain HTTP/1 · TLS 20,384
(95 MiB / 52.8% CPU)
20,198
(95 MiB / 52.5% CPU)
1× 0.99×
HTTP/1 · plain HTTP/2 · plain 35,601
(110 MiB / 48% CPU)
35,122
(105 MiB / 49.1% CPU)
0.96× 0.95×
HTTP/1 · plain HTTP/2 · TLS 39,383
(120 MiB / 48.3% CPU)
38,670
(120 MiB / 47.9% CPU)
1× 0.98×
HTTP/1 · plain HTTP/3 · QUIC 18,054
(103 MiB / 53.2% CPU)
17,685
(107 MiB / 52.2% CPU)
1.57× 1.54×
HTTP/1 · TLS HTTP/1 · plain 19,722
(94 MiB / 51.6% CPU)
19,661
(96 MiB / 51.5% CPU)
0.98× 0.97×
HTTP/1 · TLS HTTP/1 · TLS 23,590
(95 MiB / 48.8% CPU)
23,182
(96 MiB / 46.8% CPU)
1× 0.99×
HTTP/1 · TLS HTTP/2 · plain 27,300
(110 MiB / 48.4% CPU)
26,872
(112 MiB / 47.3% CPU)
0.98× 0.97×
HTTP/1 · TLS HTTP/2 · TLS 25,107
(124 MiB / 45.4% CPU)
24,748
(127 MiB / 47.5% CPU)
1× 0.99×
HTTP/1 · TLS HTTP/3 · QUIC 18,795
(112 MiB / 50.6% CPU)
18,674
(115 MiB / 53.7% CPU)
0.97× 0.96×
HTTP/2 · plain HTTP/1 · plain 33,811
(97 MiB / 55.8% CPU)
33,355
(100 MiB / 55.9% CPU)
0.97× 0.96×
HTTP/2 · plain HTTP/1 · TLS 29,166
(105 MiB / 53.2% CPU)
28,519
(103 MiB / 55.1% CPU)
0.98× 0.96×
HTTP/2 · plain HTTP/2 · plain 90,897
(69 MiB / 41.3% CPU)
84,998
(70 MiB / 43% CPU)
0.79× 0.74×
HTTP/2 · plain HTTP/2 · TLS 70,465
(78 MiB / 38.9% CPU)
66,829
(79 MiB / 38.1% CPU)
0.82× 0.77×
HTTP/2 · plain HTTP/3 · QUIC 31,297
(116 MiB / 54.3% CPU)
30,424
(115 MiB / 55.6% CPU)
0.99× 0.96×
HTTP/2 · TLS HTTP/1 · plain 38,437
(103 MiB / 53.4% CPU)
37,561
(112 MiB / 51.9% CPU)
0.98× 0.96×
HTTP/2 · TLS HTTP/1 · TLS 28,202
(105 MiB / 55.9% CPU)
27,538
(102 MiB / 54.8% CPU)
0.96× 0.93×
HTTP/2 · TLS HTTP/2 · plain 79,360
(87 MiB / 40.9% CPU)
74,807
(87 MiB / 40.4% CPU)
0.79× 0.74×
HTTP/2 · TLS HTTP/2 · TLS 74,209
(81 MiB / 39.1% CPU)
70,572
(85 MiB / 39.3% CPU)
0.84× 0.79×
HTTP/2 · TLS HTTP/3 · QUIC 30,269
(131 MiB / 53.9% CPU)
29,544
(130 MiB / 52.9% CPU)
1× 0.98×
HTTP/3 · QUIC HTTP/1 · plain 13,942
(113 MiB / 45.5% CPU)
13,712
(111 MiB / 46.6% CPU)
0.97× 0.95×
HTTP/3 · QUIC HTTP/1 · TLS 16,217
(120 MiB / 44% CPU)
15,113
(124 MiB / 44.8% CPU)
0.92× 0.86×
HTTP/3 · QUIC HTTP/2 · plain 31,662
(139 MiB / 51.8% CPU)
29,770
(139 MiB / 50.7% CPU)
0.93× 0.87×
HTTP/3 · QUIC HTTP/2 · TLS 28,483
(130 MiB / 49.9% CPU)
27,720
(133 MiB / 48.2% CPU)
0.91× 0.89×
HTTP/3 · QUIC HTTP/3 · QUIC 17,584
(123 MiB / 45.2% CPU)
23,082
(123 MiB / 46.4% CPU)
1.01× 1.33×

Linux — Titanium vs nginx vs HAProxy vs Envoy vs YARP

Reverse

Median of 3 repeats on ubuntu-latest (4 vCPU / 16 GiB). Bare reverse 5×5 @ 8bfa7852 — compare-product 35092827644. Warmup 2s / measure 8s; concurrency 8, 16, 32, 64. Linux nginx is the authoritative nginx baseline. HAProxy (3.2 USE_QUIC) and Envoy (GitHub release, HTTP/3 compiled in) run on the same loopback shape as nginx/YARP. nginx terminate peers use keepalive 256 + streaming buffers. The RPS workflow installs nginx.org mainline (http_v3_module), a QUIC-enabled HAProxy, Envoy, and libmsquic. Prefer ratios over absolute RPS. Product 5×5 is ~56-byte JSON keep-alive GET; H2/H3 same-protocol cells are mostly header work with a tiny body (Titanium best case) — see Why this comparison is fair.

Client Origin TWP nginx HAProxy Envoy YARP
HTTP/1 · plain HTTP/1 · plain 52,118
(95 MiB / 48.8% CPU)
🥇 70,158
(76 MiB / 38.3% CPU)
66,062
(64 MiB / 41.8% CPU)
38,126
(116 MiB / 59.3% CPU)
47,079
(115 MiB / 49.4% CPU)
HTTP/1 · plain HTTP/1 · TLS 23,523
(107 MiB / 51.1% CPU)
28,019
(92 MiB / 42.1% CPU)
🥇 28,193
(68 MiB / 43.6% CPU)
17,450
(118 MiB / 59% CPU)
21,545
(127 MiB / 50.3% CPU)
HTTP/1 · plain HTTP/2 · plain 🥇 40,142
(129 MiB / 51.1% CPU)
Not possible (no H2 upstream) 26,857
(65 MiB / 42.4% CPU)
22,067
(116 MiB / 63.3% CPU)
35,268
(126 MiB / 48.8% CPU)
HTTP/1 · plain HTTP/2 · TLS 51,676
(158 MiB / 48.4% CPU)
Not possible (no H2 upstream) 🥇 54,114
(68 MiB / 41% CPU)
37,450
(117 MiB / 57.4% CPU)
48,422
(131 MiB / 48.2% CPU)
HTTP/1 · plain HTTP/3 · QUIC 🥇 23,529
(143 MiB / 53.6% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 10,746
(120 MiB / 56.1% CPU)
21,315
(156 MiB / 49.2% CPU)
HTTP/1 · TLS HTTP/1 · plain 22,984
(112 MiB / 49.8% CPU)
🥇 27,706
(100 MiB / 41.6% CPU)
27,584
(83 MiB / 43.2% CPU)
17,122
(127 MiB / 58% CPU)
20,033
(134 MiB / 50.2% CPU)
HTTP/1 · TLS HTTP/1 · TLS 35,195
(112 MiB / 45.8% CPU)
43,625
(105 MiB / 38.9% CPU)
🥇 44,407
(84 MiB / 40.7% CPU)
30,389
(127 MiB / 53.8% CPU)
31,410
(143 MiB / 48.3% CPU)
HTTP/1 · TLS HTTP/2 · plain 🥇 27,813
(141 MiB / 50.6% CPU)
Not possible (no H2 upstream) 21,585
(84 MiB / 42.3% CPU)
18,519
(126 MiB / 58.2% CPU)
25,000
(148 MiB / 49.7% CPU)
HTTP/1 · TLS HTTP/2 · TLS 🥇 24,173
(155 MiB / 48.7% CPU)
Not possible (no H2 upstream) 23,923
(84 MiB / 43.3% CPU)
17,323
(126 MiB / 57.5% CPU)
22,008
(148 MiB / 47.6% CPU)
HTTP/1 · TLS HTTP/3 · QUIC 🥇 26,290
(157 MiB / 51.9% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 17,802
(130 MiB / 52.4% CPU)
24,262
(171 MiB / 49.8% CPU)
HTTP/2 · plain HTTP/1 · plain 🥇 36,694
(120 MiB / 53.3% CPU)
16,440
(79 MiB / 19% CPU)
23,041
(66 MiB / 24.6% CPU)
13,601
(118 MiB / 23.2% CPU)
34,322
(114 MiB / 50.2% CPU)
HTTP/2 · plain HTTP/1 · TLS 🥇 27,336
(129 MiB / 51% CPU)
12,859
(100 MiB / 19.6% CPU)
18,613
(70 MiB / 24.6% CPU)
12,985
(119 MiB / 23.4% CPU)
25,795
(127 MiB / 51% CPU)
HTTP/2 · plain HTTP/2 · plain 🥇 118,021
(89 MiB / 36% CPU)
Not possible (no H2 upstream) 48,169
(68 MiB / 24.2% CPU)
25,730
(116 MiB / 21.3% CPU)
68,950
(137 MiB / 48% CPU)
HTTP/2 · plain HTTP/2 · TLS 🥇 58,227
(86 MiB / 35.1% CPU)
Not possible (no H2 upstream) 19,761
(69 MiB / 24.6% CPU)
15,929
(118 MiB / 21.6% CPU)
39,519
(128 MiB / 45.6% CPU)
HTTP/2 · plain HTTP/3 · QUIC 🥇 27,742
(147 MiB / 50.5% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 4,280
(121 MiB / 24.9% CPU)
26,149
(153 MiB / 46.4% CPU)
HTTP/2 · TLS HTTP/1 · plain 🥇 49,222
(125 MiB / 49.5% CPU)
30,623
(102 MiB / 19.1% CPU)
40,300
(81 MiB / 24.3% CPU)
22,680
(129 MiB / 22.7% CPU)
45,846
(123 MiB / 47.7% CPU)
HTTP/2 · TLS HTTP/1 · TLS 🥇 26,240
(122 MiB / 50.9% CPU)
12,497
(110 MiB / 19.9% CPU)
16,768
(85 MiB / 24.4% CPU)
13,048
(128 MiB / 23.3% CPU)
23,132
(133 MiB / 50.3% CPU)
HTTP/2 · TLS HTTP/2 · plain 🥇 75,608
(99 MiB / 36.6% CPU)
Not possible (no H2 upstream) 21,385
(82 MiB / 24.4% CPU)
17,016
(126 MiB / 22.1% CPU)
39,430
(130 MiB / 47.6% CPU)
HTTP/2 · TLS HTTP/2 · TLS 🥇 81,336
(101 MiB / 34.1% CPU)
Not possible (no H2 upstream) 38,308
(82 MiB / 24.2% CPU)
24,040
(126 MiB / 21.6% CPU)
46,396
(129 MiB / 44% CPU)
HTTP/2 · TLS HTTP/3 · QUIC 🥇 25,960
(154 MiB / 50.3% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 4,339
(129 MiB / 24.8% CPU)
22,717
(154 MiB / 47% CPU)
HTTP/3 · QUIC HTTP/1 · plain 20,471
(147 MiB / 50% CPU)
0
(peak 15,362 · 106 MiB / 22.5% CPU)
🥇 23,011
(87 MiB / 26.3% CPU)
3,989
(136 MiB / 24.8% CPU)
18,716
(183 MiB / 50.2% CPU)
HTTP/3 · QUIC HTTP/1 · TLS 23,817
(165 MiB / 45.2% CPU)
0
(peak 27,931 · 123 MiB / 20.1% CPU)
🥇 29,255
(91 MiB / 25.8% CPU)
14
(136 MiB / 0.1% CPU)
22,334
(203 MiB / 47.7% CPU)
HTTP/3 · QUIC HTTP/2 · plain 🥇 28,969
(158 MiB / 53% CPU)
Not possible (no H2 upstream) 24,863
(86 MiB / 25.8% CPU)
26
(130 MiB / 0.2% CPU)
23,885
(197 MiB / 48.2% CPU)
HTTP/3 · QUIC HTTP/2 · TLS 🥇 25,108
(157 MiB / 50.6% CPU)
Not possible (no H2 upstream) 20,697
(88 MiB / 25.4% CPU)
1,471
(132 MiB / 7.8% CPU)
21,179
(196 MiB / 47.3% CPU)
HTTP/3 · QUIC HTTP/3 · QUIC 🥇 22,764
(170 MiB / 44.9% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 448
(130 MiB / 2.2% CPU)
19,268
(210 MiB / 47.5% CPU)

MITM (TWP only)

Same Client×Origin wires with interception on (compare-product 35092827644). Lite = no-op handlers (unchanged-lite finish). Full = append-only header mutation (harness: one probe header each way; product: generic append-only relay via MitmCompressedRelayHelper). nginx/HAProxy/Envoy/YARP cannot MITM. Lite÷Reverse / Full÷Reverse vs bare reverse (same job / comparison-group shard). Completion gate: Lite ≥ 0.50× and Full ≥ 0.50× reverse sustain @ c=64 (median of 3 GHA runs); reverse TWP÷YARP ≥ 0.75× (no terminate-peer gate).

v1 append-only relay (2026-08-27): Pre-fix H2→H2 Full÷Reverse was 0.13–0.16× (32960766249). Post-fix @ df172718: H2 plain→H2 plain Full 0.77–0.79×, H3→H1 Full 0.91–0.93×, all MITM arms ≥ 0.70× on median of 33041445371, 33055267086, 33055272140.

v2 drop-only + non-unique append (2026-08-27): MitmStaticRebuildHelper rebuilds static HPACK/QPACK after 1–4 unique header drops; trailing non-unique appends stay on compressed relay. @ 8bfa7852: all MITM arms ≥ 0.70× on GHA median (33087088466, 33087091622, 33105885748 Linux; 33087085235, 33087088466, 33087091622 Windows). H2 plain→H2 plain Full 0.77–0.79× (Win) / 0.78× (Lin).

Client Origin Lite sustain Full sustain Lite÷Reverse Full÷Reverse
HTTP/1 · plain HTTP/1 · plain 51,441
(97 MiB / 50.2% CPU)
50,516
(98 MiB / 49.8% CPU)
0.99× 0.97×
HTTP/1 · plain HTTP/1 · TLS 23,548
(112 MiB / 52.2% CPU)
23,482
(113 MiB / 51.3% CPU)
1× 1×
HTTP/1 · plain HTTP/2 · plain 40,450
(132 MiB / 53.8% CPU)
38,305
(126 MiB / 53% CPU)
1.01× 0.95×
HTTP/1 · plain HTTP/2 · TLS 50,652
(153 MiB / 50.5% CPU)
49,728
(154 MiB / 50.8% CPU)
0.98× 0.96×
HTTP/1 · plain HTTP/3 · QUIC 22,774
(142 MiB / 54.2% CPU)
22,822
(137 MiB / 54.3% CPU)
0.97× 0.97×
HTTP/1 · TLS HTTP/1 · plain 23,114
(115 MiB / 50.9% CPU)
22,808
(116 MiB / 50.3% CPU)
1.01× 0.99×
HTTP/1 · TLS HTTP/1 · TLS 34,966
(117 MiB / 46.7% CPU)
34,270
(118 MiB / 46.8% CPU)
0.99× 0.97×
HTTP/1 · TLS HTTP/2 · plain 27,488
(143 MiB / 51.3% CPU)
26,553
(148 MiB / 51.2% CPU)
0.99× 0.95×
HTTP/1 · TLS HTTP/2 · TLS 23,559
(170 MiB / 48.9% CPU)
23,089
(169 MiB / 48.7% CPU)
0.97× 0.96×
HTTP/1 · TLS HTTP/3 · QUIC 25,937
(156 MiB / 52.5% CPU)
26,697
(161 MiB / 53.2% CPU)
0.99× 1.02×
HTTP/2 · plain HTTP/1 · plain 36,272
(120 MiB / 54.6% CPU)
34,343
(120 MiB / 54.4% CPU)
0.99× 0.94×
HTTP/2 · plain HTTP/1 · TLS 27,164
(124 MiB / 52.4% CPU)
26,445
(129 MiB / 52.2% CPU)
0.99× 0.97×
HTTP/2 · plain HTTP/2 · plain 88,034
(101 MiB / 40.5% CPU)
81,934
(98 MiB / 40.2% CPU)
0.75× 0.69×
HTTP/2 · plain HTTP/2 · TLS 48,275
(95 MiB / 40.2% CPU)
45,097
(98 MiB / 40.2% CPU)
0.83× 0.77×
HTTP/2 · plain HTTP/3 · QUIC 27,595
(143 MiB / 50.5% CPU)
27,350
(147 MiB / 51.1% CPU)
0.99× 0.99×
HTTP/2 · TLS HTTP/1 · plain 48,535
(132 MiB / 50.6% CPU)
46,791
(134 MiB / 50% CPU)
0.99× 0.95×
HTTP/2 · TLS HTTP/1 · TLS 25,779
(123 MiB / 51.8% CPU)
25,125
(129 MiB / 52.1% CPU)
0.98× 0.96×
HTTP/2 · TLS HTTP/2 · plain 55,993
(110 MiB / 41.3% CPU)
53,218
(114 MiB / 41% CPU)
0.74× 0.7×
HTTP/2 · TLS HTTP/2 · TLS 64,140
(113 MiB / 36.2% CPU)
60,738
(112 MiB / 36.2% CPU)
0.79× 0.75×
HTTP/2 · TLS HTTP/3 · QUIC 26,305
(160 MiB / 51.5% CPU)
25,709
(152 MiB / 50.6% CPU)
1.01× 0.99×
HTTP/3 · QUIC HTTP/1 · plain 19,415
(144 MiB / 50.9% CPU)
19,586
(145 MiB / 50.1% CPU)
0.95× 0.96×
HTTP/3 · QUIC HTTP/1 · TLS 23,253
(171 MiB / 47.3% CPU)
22,767
(170 MiB / 46% CPU)
0.98× 0.96×
HTTP/3 · QUIC HTTP/2 · plain 27,212
(160 MiB / 54.2% CPU)
26,934
(163 MiB / 54.5% CPU)
0.94× 0.93×
HTTP/3 · QUIC HTTP/2 · TLS 23,551
(152 MiB / 51.9% CPU)
22,624
(153 MiB / 51.9% CPU)
0.94× 0.9×
HTTP/3 · QUIC HTTP/3 · QUIC 21,049
(171 MiB / 48.3% CPU)
20,830
(171 MiB / 48.2% CPU)
0.92× 0.92×

macOS — Titanium vs nginx vs HAProxy vs Envoy vs YARP

Reverse

Median of 3 repeats on macos-15-intel (4-core / 14 GB). Bare reverse 5×5 @ 8bfa7852 — compare-product 35092827644. Warmup 2s / measure 8s; concurrency 8, 16, 32, 64. Prefer TWP÷peer ratios over absolute RPS. RPS cells include median RSS / CPU at the peak-RPS step as <br><sub>(MiB / CPU%)</sub>. The RPS workflow installs Homebrew nginx (http_v3_module), Homebrew HAProxy with USE_QUIC (3.2 source fallback), Envoy (Homebrew bottle or pinned darwin-amd64 1.36.7), Homebrew libmsquic (+ DYLD_*), and YARP. Do not publish from macos-latest (3-core / 7 GB). Product 5×5 is ~56-byte JSON keep-alive GET; H2/H3 same-protocol cells are mostly header work with a tiny body (Titanium best case) — see Why this comparison is fair.

Client Origin TWP nginx HAProxy Envoy YARP
HTTP/1 · plain HTTP/1 · plain 🥇 16,348
(84 MiB / 39.4% CPU)
9,898
(52 MiB / 18.6% CPU)
15,804
(50 MiB / 31.4% CPU)
6,117
(72 MiB / 41.8% CPU)
13,286
(104 MiB / 41.2% CPU)
HTTP/1 · plain HTTP/1 · TLS 🥇 12,783
(94 MiB / 43.1% CPU)
5,967
(74 MiB / 18.6% CPU)
12,525
(55 MiB / 33.2% CPU)
5,670
(73 MiB / 48% CPU)
9,909
(124 MiB / 40.9% CPU)
HTTP/1 · plain HTTP/2 · plain 🥇 20,904
(88 MiB / 43.3% CPU)
Not possible (no H2 upstream) 8,778
(51 MiB / 30.6% CPU)
6,122
(71 MiB / 44.3% CPU)
15,420
(112 MiB / 40.6% CPU)
HTTP/1 · plain HTTP/2 · TLS 13,267
(101 MiB / 37.9% CPU)
Not possible (no H2 upstream) 12,220
(52 MiB / 31.2% CPU)
7,310
(73 MiB / 48.7% CPU)
🥇 18,474
(116 MiB / 41.3% CPU)
HTTP/1 · plain HTTP/3 · QUIC 4,693
(89 MiB / 48.9% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 3,091
(75 MiB / 23.7% CPU)
🥇 5,445
(115 MiB / 38.5% CPU)
HTTP/1 · TLS HTTP/1 · plain 7,955
(94 MiB / 34.9% CPU)
6,371
(74 MiB / 25.2% CPU)
7,738
(65 MiB / 31.1% CPU)
6,444
(80 MiB / 41.2% CPU)
🥇 8,665
(132 MiB / 38.8% CPU)
HTTP/1 · TLS HTTP/1 · TLS 8,977
(98 MiB / 36.1% CPU)
5,494
(83 MiB / 18.9% CPU)
🥇 9,125
(68 MiB / 35.1% CPU)
3,695
(81 MiB / 37.8% CPU)
7,820
(139 MiB / 37.4% CPU)
HTTP/1 · TLS HTTP/2 · plain 9,860
(97 MiB / 39.1% CPU)
Not possible (no H2 upstream) 7,800
(66 MiB / 32.1% CPU)
5,521
(79 MiB / 45.2% CPU)
🥇 10,651
(118 MiB / 34.5% CPU)
HTTP/1 · TLS HTTP/2 · TLS 7,860
(163 MiB / 37% CPU)
Not possible (no H2 upstream) 7,448
(66 MiB / 35.7% CPU)
4,624
(79 MiB / 40.9% CPU)
🥇 11,054
(127 MiB / 34.9% CPU)
HTTP/1 · TLS HTTP/3 · QUIC 2,705
(109 MiB / 46.2% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 3,636
(81 MiB / 32.3% CPU)
🥇 4,619
(123 MiB / 35.2% CPU)
HTTP/2 · plain HTTP/1 · plain 🥇 16,372
(91 MiB / 42.4% CPU)
15,429
(58 MiB / 18.7% CPU)
10,220
(56 MiB / 20.3% CPU)
3,692
(75 MiB / 22.4% CPU)
14,817
(105 MiB / 44.2% CPU)
HTTP/2 · plain HTTP/1 · TLS 🥇 12,382
(94 MiB / 46.4% CPU)
7,196
(85 MiB / 18.3% CPU)
5,558
(59 MiB / 20.8% CPU)
3,155
(77 MiB / 21.5% CPU)
12,044
(125 MiB / 45.8% CPU)
HTTP/2 · plain HTTP/2 · plain 🥇 36,700
(73 MiB / 30.8% CPU)
Not possible (no H2 upstream) 9,528
(57 MiB / 19.9% CPU)
6,036
(72 MiB / 22% CPU)
24,939
(111 MiB / 40.4% CPU)
HTTP/2 · plain HTTP/2 · TLS 🥇 30,656
(77 MiB / 30.9% CPU)
Not possible (no H2 upstream) 8,666
(58 MiB / 20.9% CPU)
5,469
(73 MiB / 21.3% CPU)
26,491
(114 MiB / 38.9% CPU)
HTTP/2 · plain HTTP/3 · QUIC 5,092
(95 MiB / 56.1% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 1,973
(75 MiB / 22.8% CPU)
🥇 5,453
(118 MiB / 39.1% CPU)
HTTP/2 · TLS HTTP/1 · plain 🥇 15,856
(92 MiB / 44.7% CPU)
9,770
(73 MiB / 18.1% CPU)
8,427
(67 MiB / 21.2% CPU)
3,491
(81 MiB / 21.4% CPU)
12,707
(115 MiB / 43.2% CPU)
HTTP/2 · TLS HTTP/1 · TLS 🥇 13,319
(96 MiB / 44.8% CPU)
6,541
(91 MiB / 19% CPU)
8,793
(69 MiB / 21.4% CPU)
3,229
(83 MiB / 21.7% CPU)
11,692
(123 MiB / 44.6% CPU)
HTTP/2 · TLS HTTP/2 · plain 🥇 27,511
(84 MiB / 31.1% CPU)
Not possible (no H2 upstream) 8,259
(68 MiB / 20.9% CPU)
5,966
(79 MiB / 21.7% CPU)
19,566
(112 MiB / 42.1% CPU)
HTTP/2 · TLS HTTP/2 · TLS 🥇 30,544
(84 MiB / 31.1% CPU)
Not possible (no H2 upstream) 7,040
(68 MiB / 21.3% CPU)
5,660
(79 MiB / 21.4% CPU)
19,845
(116 MiB / 40.9% CPU)
HTTP/2 · TLS HTTP/3 · QUIC 5,713
(106 MiB / 45.9% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 2,513
(80 MiB / 22.9% CPU)
🥇 7,097
(121 MiB / 40.4% CPU)
HTTP/3 · QUIC HTTP/1 · plain 4,598
(100 MiB / 46.2% CPU)
0
(peak 6,020 · 62 MiB / 13.4% CPU)
🥇 9,237
(67 MiB / 23.9% CPU)
1,238
(86 MiB / 23.4% CPU)
4,568
(183 MiB / 39% CPU)
HTTP/3 · QUIC HTTP/1 · TLS 4,263
(117 MiB / 43.4% CPU)
0
(peak 7,101 · 67 MiB / 16.4% CPU)
🥇 8,098
(69 MiB / 27.4% CPU)
1,138
(87 MiB / 27.8% CPU)
5,599
(204 MiB / 41.9% CPU)
HTTP/3 · QUIC HTTP/2 · plain 6,267
(97 MiB / 45% CPU)
Not possible (no H2 upstream) 🥇 8,644
(67 MiB / 21.8% CPU)
2,182
(83 MiB / 31.8% CPU)
6,180
(179 MiB / 38.4% CPU)
HTTP/3 · QUIC HTTP/2 · TLS 5,881
(107 MiB / 46% CPU)
Not possible (no H2 upstream) 🥇 8,089
(69 MiB / 24.6% CPU)
2,252
(84 MiB / 30.9% CPU)
7,557
(171 MiB / 39.6% CPU)
HTTP/3 · QUIC HTTP/3 · QUIC 3,988
(97 MiB / 39.4% CPU)
Not possible (no H3 upstream) Not possible (no H3 upstream) 904
(81 MiB / 27.3% CPU)
🥇 4,700
(182 MiB / 40.8% CPU)

MITM (TWP only)

Same Client×Origin wires with interception on (compare-product 35092827644). Lite = no-op handlers (unchanged-lite finish). Full = append-only header mutation (harness: one probe header each way; product: generic append-only relay via MitmCompressedRelayHelper). nginx/HAProxy/Envoy/YARP cannot MITM. Lite÷Reverse / Full÷Reverse vs bare reverse (same job / comparison-group shard). Completion gate: Lite ≥ 0.50× and Full ≥ 0.50× reverse sustain @ c=64 (median of 3 GHA runs); reverse TWP÷YARP ≥ 0.75× (no terminate-peer gate).

v1 append-only relay (2026-08-27): Pre-fix H2→H2 Full÷Reverse was 0.13–0.16× (32960766249). Post-fix @ df172718: H2 plain→H2 plain Full 0.77–0.79×, H3→H1 Full 0.91–0.93×, all MITM arms ≥ 0.70× on median of 33041445371, 33055267086, 33055272140.

v2 drop-only + non-unique append (2026-08-27): MitmStaticRebuildHelper rebuilds static HPACK/QPACK after 1–4 unique header drops; trailing non-unique appends stay on compressed relay. @ 8bfa7852: all MITM arms ≥ 0.70× on GHA median (33087088466, 33087091622, 33105885748 Linux; 33087085235, 33087088466, 33087091622 Windows). H2 plain→H2 plain Full 0.77–0.79× (Win) / 0.78× (Lin).

Client Origin Lite sustain Full sustain Lite÷Reverse Full÷Reverse
HTTP/1 · plain HTTP/1 · plain 13,180
(84 MiB / 39.4% CPU)
13,546
(85 MiB / 38.2% CPU)
0.81× 0.83×
HTTP/1 · plain HTTP/1 · TLS 11,128
(95 MiB / 40% CPU)
10,009
(94 MiB / 37.9% CPU)
0.87× 0.78×
HTTP/1 · plain HTTP/2 · plain 18,046
(91 MiB / 44.7% CPU)
12,264
(93 MiB / 43.8% CPU)
0.86× 0.59×
HTTP/1 · plain HTTP/2 · TLS 12,795
(106 MiB / 40.2% CPU)
17,562
(106 MiB / 42.6% CPU)
0.96× 1.32×
HTTP/1 · plain HTTP/3 · QUIC 4,402
(91 MiB / 47.8% CPU)
4,047
(93 MiB / 45.6% CPU)
0.94× 0.86×
HTTP/1 · TLS HTTP/1 · plain 11,591
(95 MiB / 39.4% CPU)
7,671
(96 MiB / 38.9% CPU)
1.46× 0.96×
HTTP/1 · TLS HTTP/1 · TLS 8,412
(99 MiB / 37.9% CPU)
10,725
(99 MiB / 38.9% CPU)
0.94× 1.19×
HTTP/1 · TLS HTTP/2 · plain 10,748
(100 MiB / 41.7% CPU)
9,978
(105 MiB / 39.5% CPU)
1.09× 1.01×
HTTP/1 · TLS HTTP/2 · TLS 11,660
(161 MiB / 39.5% CPU)
6,751
(156 MiB / 37.8% CPU)
1.48× 0.86×
HTTP/1 · TLS HTTP/3 · QUIC 2,975
(98 MiB / 54.7% CPU)
3,009
(103 MiB / 49.8% CPU)
1.1× 1.11×
HTTP/2 · plain HTTP/1 · plain 16,657
(90 MiB / 43.4% CPU)
16,350
(90 MiB / 44.4% CPU)
1.02× 1×
HTTP/2 · plain HTTP/1 · TLS 14,896
(98 MiB / 46.9% CPU)
11,821
(97 MiB / 47% CPU)
1.2× 0.95×
HTTP/2 · plain HTTP/2 · plain 28,786
(79 MiB / 34.8% CPU)
29,833
(76 MiB / 36.4% CPU)
0.78× 0.81×
HTTP/2 · plain HTTP/2 · TLS 26,546
(80 MiB / 38.2% CPU)
34,124
(83 MiB / 36.4% CPU)
0.87× 1.11×
HTTP/2 · plain HTTP/3 · QUIC 4,078
(95 MiB / 52.4% CPU)
4,254
(94 MiB / 53.3% CPU)
0.8× 0.84×
HTTP/2 · TLS HTTP/1 · plain 15,130
(95 MiB / 48.3% CPU)
15,199
(92 MiB / 45.1% CPU)
0.95× 0.96×
HTTP/2 · TLS HTTP/1 · TLS 15,237
(100 MiB / 41.4% CPU)
13,176
(97 MiB / 47% CPU)
1.14× 0.99×
HTTP/2 · TLS HTTP/2 · plain 26,045
(87 MiB / 38% CPU)
31,311
(86 MiB / 36.2% CPU)
0.95× 1.14×
HTTP/2 · TLS HTTP/2 · TLS 29,113
(89 MiB / 36.4% CPU)
28,038
(90 MiB / 38.6% CPU)
0.95× 0.92×
HTTP/2 · TLS HTTP/3 · QUIC 5,228
(107 MiB / 46.1% CPU)
3,875
(107 MiB / 45.1% CPU)
0.92× 0.68×
HTTP/3 · QUIC HTTP/1 · plain 4,428
(101 MiB / 45.8% CPU)
5,675
(102 MiB / 47.5% CPU)
0.96× 1.23×
HTTP/3 · QUIC HTTP/1 · TLS 4,527
(116 MiB / 46.2% CPU)
4,613
(116 MiB / 44.1% CPU)
1.06× 1.08×
HTTP/3 · QUIC HTTP/2 · plain 5,291
(99 MiB / 49.4% CPU)
4,946
(99 MiB / 48.2% CPU)
0.84× 0.79×
HTTP/3 · QUIC HTTP/2 · TLS 4,271
(105 MiB / 46.1% CPU)
4,538
(107 MiB / 48.8% CPU)
0.73× 0.77×
HTTP/3 · QUIC HTTP/3 · QUIC 3,764
(95 MiB / 57.2% CPU)
4,233
(93 MiB / 41.9% CPU)
0.94× 1.06×

Editions (CLI / Plus / Intercept)

Note: twp-reverse-http1 and other library rows use Core with probe-tuned settings (no logging, no Via header, probe-warmed certs). Edition rows use titanium run -c twp.yaml product defaults — prefer the ÷baseline ratio column over absolute RPS. Inspector GUI is not spawnable in the harness; session-path overhead is twp-cli-intercept-http1 (route RequestHeaderSet transform). Pre-origin Plus middleware (CIDR/WAF/JWT/rate-limit) runs on H1 terminate-lite without SessionEventArgs; JWT caches successful bearer validations. Maintainer gate thresholds live under Maintainer notes.

Median of 3 repeats @ 6d2a7c9d. Source: Actions 33259699099. Warmup 2s / measure 8s; concurrency 8–64; sustain = median peak RPS among SLO-pass steps @ c=64. RPS cells show sustain; <sub> holds peak (when higher) plus (MiB / CPU%).

Arm Win Linux Win÷ Lin÷ Gate
twp-cli-reverse-http1 vs library 32,214
(peak 32,219 · 118 MiB / 43.4% CPU)
47,734
(peak 47,844 · 151 MiB / 49.0% CPU)
1.02× 1.04× ≥ 0.80×
twp-cli-reverse-http1-tls vs library TLS 26,495
(peak 26,651 · 138 MiB / 48.3% CPU)
36,932
(peak 37,200 · 174 MiB / 48.5% CPU)
1.01× 1.00× ≥ 0.80×
twp-cli-reverse-http1-route vs CLI 32,394
(peak 32,428 · 120 MiB / 47.7% CPU)
47,369
(peak 47,398 · 149 MiB / 49.2% CPU)
1.01× 0.99× ≥ 0.90×
twp-cli-plus-base-http1 vs CLI 32,475
(peak 32,695 · 123 MiB / 46.0% CPU)
47,322
(peak 47,744 · 154 MiB / 49.8% CPU)
1.01× 0.99× ≥ 0.90×
twp-cli-plus-cache-http1 (cold) vs CLI 34,029
(peak 34,460 · 118 MiB / 64.5% CPU)
49,409
(peak 50,104 · 148 MiB / 62.3% CPU)
1.06× 1.04× ≥ 0.70×
twp-cli-intercept-http1 vs CLI 25,219
(peak 25,377 · 124 MiB / 54.0% CPU)
35,969
(peak 35,977 · 155 MiB / 51.2% CPU)
0.78× 0.75× ≥ 0.70×
twp-cli-plus-waf-http1 vs CLI 31,653
(peak 31,837 · 124 MiB / 46.8% CPU)
46,367
(peak 46,685 · 151 MiB / 49.6% CPU)
0.98× 0.97× ≥ 0.80×
twp-cli-plus-cidr-http1 vs CLI 31,730
(peak 31,757 · 123 MiB / 51.1% CPU)
46,828
(peak 47,093 · 150 MiB / 50.2% CPU)
0.98× 0.98× ≥ 0.80×
twp-cli-plus-jwt-http1 vs CLI 30,326
(peak 30,386 · 138 MiB / 46.6% CPU)
43,906
(peak 44,433 · 179 MiB / 49.5% CPU)
0.94× 0.92× ≥ 0.70×
twp-cli-plus-ratelimit-http1 vs CLI 31,713
(peak 31,944 · 123 MiB / 48.8% CPU)
46,435
(peak 46,860 · 151 MiB / 49.4% CPU)
0.98× 0.97× ≥ 0.80×
twp-cli-plus-resilience-http1 vs CLI 32,373
(peak 32,416 · 128 MiB / 50.5% CPU)
47,302
(peak 47,654 · 155 MiB / 49.5% CPU)
1.00× 0.99× ≥ 0.85×
twp-cli-plus-discovery-file-http1 vs CLI 32,209
(peak 32,332 · 121 MiB / 46.5% CPU)
47,485
(peak 47,770 · 151 MiB / 49.1% CPU)
1.00× 0.99× ≥ 0.80×
twp-cli-plus-metrics-scrape-http1 vs CLI 32,192
(peak 32,427 · 126 MiB / 44.8% CPU)
47,348
(peak 48,665 · 159 MiB / 49.5% CPU)
1.00× 0.99× ≥ 0.80×
twp-cli-plus-cache-hit-http1 vs cache cold 34,015
(peak 34,022 · 117 MiB / 66.0% CPU)
49,153
(peak 49,358 · 149 MiB / 63.1% CPU)
1.00× 0.99× ≥ 0.90×
twp-cli-static-http1 vs CLI 53,078
(peak 53,980 · 109 MiB / 52.1% CPU)
78,333
(peak 82,955 · 150 MiB / 48.4% CPU)
1.65× 1.64× ≥ 0.85×
twp-cli-logging-http1 vs CLI 32,440
(peak 32,581 · 119 MiB / 47.4% CPU)
47,624
(peak 48,604 · 150 MiB / 49.3% CPU)
1.01× 1.00× ≥ 0.90×
twp-cli-lb-leasttime-http1 vs route 29,649
(peak 30,386 · 134 MiB / 54.7% CPU)
44,790
(peak 44,825 · 180 MiB / 50.6% CPU)
0.92× 0.95× ≥ 0.85×
twp-cli-dialect-twp-http1 vs CLI 32,461
(peak 32,780 · 114 MiB / 49.7% CPU)
47,898
(peak 48,154 · 145 MiB / 49.3% CPU)
1.01× 1.00× ≥ 0.90×

validate-edition-gates.ps1 passed on both OS for this run. Library baselines @ c=64 (same job): Win H1 31561 / TLS 26128; Linux H1 45818 / TLS 36869. Laptop smoke ratios stay on Performance Local Lab — Editions.

Cross-version (7.0 vs 6.0)

Same reverse matrix measured on Titanium 7.0 versus committed 6.0 baselines (33087088466). Median of 3 @ 0ef6d4dd. Source: Actions 33270571908. Sustain RPS @ c=64. Absolute 7.0÷6.0 ≈ 0.96–1.00× on same-protocol arms; peer-normalized ratios ≈ 0.90–1.03×.

Arm Win 6.0 Win 7.0 Win÷ Linux 6.0 Linux 7.0 Lin÷
twp-reverse-http1 32525 32213 0.99× 32755 31932 0.97×
twp-reverse-http1-tls 26461 26570 1.00× 22784 22351 0.98×
twp-reverse-http2 76038 75316 0.99× 47690 46678 0.98×
twp-reverse-http2-cleartext 40347 40236 1.00× 34556 33316 0.96×
twp-reverse-http3 17529 17380 0.99× 19468 19423 1.00×
twp-reverse-http3-cleartext 19956 19529 0.98× 20395 20070 0.98×
yarp-reverse-http1 (peer) 27504 27254 0.99× 27713 27102 0.98×
yarp-reverse-http2 (peer) 35553 35189 0.99× 29111 28733 0.99×

Both OS CSVs passed the cross-version check for this run. MITM arms are measured with the product reverse matrix, not this reverse-only comparison.

Heavier reverse workloads

Same runners and harness as the tiny-GET tables, but with larger bodies, POST, lossy links, TLS cost, and architecture-sensitive paths (slow consumer / early response / duplex). PUT with the same body is the same proxy work as POST; DELETE with no body matches GET — only POST is published. Bodies/POST/lossy stay half-duplex. Laptop numbers are on Performance Local Lab. How maintainers refresh these tables (modes, shards, paste scripts) is under Maintainer notes. Larger-body check: 64 / 256 KiB H2 TLS→H2 TLS is where body copy dominates headers — Titanium is behind YARP here (~0.69–0.76× at 64 KiB), unlike the tiny-GET H2↔H2 medals above.

Lossy link = userspace delay/drop shim (not kernel netem): TCP gets per-buffer delay + occasional whole-connection stalls (honest head-of-line for multiplexed HTTP/2); UDP gets per-datagram delay + drops (QUIC). Lossy tables publish HTTP/1, HTTP/2, and HTTP/3.

Windows — heavier reverse GET (64 KiB / 256 KiB)

Median of 3 repeats on windows-latest @ 8bfa7852. Source: Actions 35092832912 (compare-bodies). Warmup 2s / measure 8s. RPS cells include (MiB / CPU%) footprints.

Not possible: HAProxy and Envoy columns are omitted (no official Windows port).

Not possible: HAProxy and Envoy columns are omitted (no official Windows port).

Not possible: HAProxy and Envoy columns are omitted (no official Windows port).

Body Client Origin TWP nginx YARP
64 KiB HTTP/1 · TLS HTTP/1 · plain 🥇 8,782
(114 MiB / 46.0% CPU)
644
(142 MiB / 24.7% CPU)
7,764
(135 MiB / 47.3% CPU)
64 KiB HTTP/2 · TLS HTTP/1 · plain 🥇 8,184
(174 MiB / 46.0% CPU)
564
(142 MiB / 24.8% CPU)
7,013
(135 MiB / 50.5% CPU)
64 KiB HTTP/3 · QUIC HTTP/1 · plain 🥇 3,876
(132 MiB / 38.6% CPU)
Not possible (no QUIC) 3,663
(188 MiB / 46.8% CPU)
256 KiB HTTP/1 · TLS HTTP/1 · plain 🥇 2,790
(129 MiB / 47.6% CPU)
0
(peak 162 · 143 MiB / 24.8% CPU)
2,586
(135 MiB / 48.0% CPU)
256 KiB HTTP/2 · TLS HTTP/1 · plain 🥇 2,537
(153 MiB / 40.3% CPU)
0
(peak 142 · 142 MiB / 24.7% CPU)
1,909
(134 MiB / 45.1% CPU)
256 KiB HTTP/3 · QUIC HTTP/1 · plain 🥇 1,121
(107 MiB / 39.8% CPU)
Not possible (no QUIC) 1,048
(170 MiB / 46.1% CPU)
64 KiB HTTP/2 · plain HTTP/1 · plain 🥇 11,532
(170 MiB / 42.4% CPU)
2,087
(127 MiB / 24.8% CPU)
9,578
(118 MiB / 45.0% CPU)
64 KiB HTTP/2 · TLS HTTP/2 · plain 3,848
(77 MiB / 35.2% CPU)
Not possible 🥇 6,673
(140 MiB / 47.9% CPU)
64 KiB HTTP/2 · TLS HTTP/2 · TLS 3,495
(78 MiB / 37.3% CPU)
Not possible 🥇 6,000
(140 MiB / 47.2% CPU)
64 KiB HTTP/3 · QUIC HTTP/2 · TLS 3,396
(125 MiB / 43.6% CPU)
Not possible 🥇 3,552
(184 MiB / 46.8% CPU)
64 KiB HTTP/3 · QUIC HTTP/1 · TLS 🥇 3,934
(138 MiB / 41.5% CPU)
Not possible (no QUIC) 3,307
(199 MiB / 49.0% CPU)
256 KiB HTTP/2 · plain HTTP/1 · plain 🥇 3,784
(144 MiB / 30.6% CPU)
655
(127 MiB / 24.3% CPU)
2,823
(123 MiB / 38.1% CPU)
256 KiB HTTP/2 · TLS HTTP/2 · plain 1,382
(86 MiB / 33.1% CPU)
Not possible 🥇 1,808
(163 MiB / 47.4% CPU)
256 KiB HTTP/2 · TLS HTTP/2 · TLS 1,277
(87 MiB / 34.7% CPU)
Not possible 🥇 1,410
(146 MiB / 44.2% CPU)
256 KiB HTTP/3 · QUIC HTTP/2 · TLS 869
(151 MiB / 42.2% CPU)
Not possible 🥇 979
(191 MiB / 44.0% CPU)
256 KiB HTTP/3 · QUIC HTTP/1 · TLS 🥇 1,090
(148 MiB / 40.6% CPU)
Not possible (no QUIC) 990
(198 MiB / 44.3% CPU)

nginx/Windows collapses on large reverse bodies in this harness; treat as same-OS only. H1 TLS 64 KiB ≈ 1.11× YARP; 256 KiB ≈ 1.23×. H2→H1 64 KiB ≈ 1.21×; H3→H1 64 KiB ≈ 1.18×.

Linux — heavier reverse GET (64 KiB / 256 KiB)

Median of 3 repeats @ 8bfa7852. Source: Actions 35092832912 (compare-bodies). Warmup 2s / measure 8s.

Body Client Origin TWP nginx HAProxy Envoy YARP
64 KiB HTTP/1 · TLS HTTP/1 · plain 8,545
(175 MiB / 44.2% CPU)
5,990
(100 MiB / 49.8% CPU)
🥇 9,584
(83 MiB / 39.5% CPU)
8,284
(132 MiB / 43.3% CPU)
7,035
(164 MiB / 47.9% CPU)
64 KiB HTTP/2 · TLS HTTP/1 · plain 🥇 5,771
(221 MiB / 40.2% CPU)
1,831
(101 MiB / 16.9% CPU)
4,786
(84 MiB / 24.4% CPU)
4,353
(140 MiB / 23.6% CPU)
4,800
(162 MiB / 48.5% CPU)
64 KiB HTTP/3 · QUIC HTTP/1 · plain 🥇 5,873
(183 MiB / 43.5% CPU)
0
(peak 1,851 · 129 MiB / 23.6% CPU)
5,030
(88 MiB / 32.8% CPU)
123
(139 MiB / 1.1% CPU)
4,568
(231 MiB / 51.3% CPU)
256 KiB HTTP/1 · TLS HTTP/1 · plain 2,794
(129 MiB / 35.7% CPU)
1,514
(100 MiB / 47.3% CPU)
🥇 3,024
(83 MiB / 32.8% CPU)
2,727
(145 MiB / 32.2% CPU)
2,211
(170 MiB / 44.0% CPU)
256 KiB HTTP/2 · TLS HTTP/1 · plain 1,563
(195 MiB / 37.2% CPU)
595
(100 MiB / 21.3% CPU)
1,588
(83 MiB / 21.1% CPU)
🥇 1,900
(158 MiB / 20.8% CPU)
1,355
(161 MiB / 45.0% CPU)
256 KiB HTTP/3 · QUIC HTTP/1 · plain 🥇 1,519
(159 MiB / 42.6% CPU)
0
(118 MiB / 20.6% CPU)
1,344
(89 MiB / 30.3% CPU)
25
(157 MiB / 0.7% CPU)
1,304
(218 MiB / 47.4% CPU)
64 KiB HTTP/2 · plain HTTP/1 · plain 🥇 9,681
(237 MiB / 42.5% CPU)
2,321
(80 MiB / 12.9% CPU)
7,167
(70 MiB / 24.3% CPU)
6,374
(132 MiB / 23.9% CPU)
8,267
(153 MiB / 45.9% CPU)
64 KiB HTTP/2 · TLS HTTP/2 · plain 3,709
(103 MiB / 38.7% CPU)
Not possible 2,594
(86 MiB / 24.7% CPU)
🥇 5,209
(144 MiB / 22.1% CPU)
4,981
(184 MiB / 46.5% CPU)
64 KiB HTTP/2 · TLS HTTP/2 · TLS 2,716
(102 MiB / 38.4% CPU)
Not possible 1,584
(83 MiB / 24.5% CPU)
3,262
(146 MiB / 23.0% CPU)
🥇 3,359
(171 MiB / 45.6% CPU)
64 KiB HTTP/3 · QUIC HTTP/2 · TLS 3,060
(164 MiB / 53.0% CPU)
Not possible 2,380
(90 MiB / 35.2% CPU)
1
(144 MiB / 0.1% CPU)
🥇 3,219
(240 MiB / 49.1% CPU)
64 KiB HTTP/3 · QUIC HTTP/1 · TLS 🥇 3,926
(203 MiB / 44.0% CPU)
0
(peak 1,472 · 143 MiB / 23.0% CPU)
3,080
(94 MiB / 31.8% CPU)
0
(140 MiB / 0.1% CPU)
3,182
(240 MiB / 49.5% CPU)
256 KiB HTTP/2 · plain HTTP/1 · plain 2,768
(211 MiB / 36.3% CPU)
877
(79 MiB / 20.1% CPU)
2,746
(70 MiB / 22.6% CPU)
🥇 3,006
(152 MiB / 22.6% CPU)
2,859
(157 MiB / 38.6% CPU)
256 KiB HTTP/2 · TLS HTTP/2 · plain 1,203
(113 MiB / 33.7% CPU)
Not possible 772
(90 MiB / 24.3% CPU)
🥇 1,769
(169 MiB / 22.0% CPU)
1,350
(187 MiB / 41.8% CPU)
256 KiB HTTP/2 · TLS HTTP/2 · TLS 804
(109 MiB / 33.0% CPU)
Not possible 433
(82 MiB / 24.6% CPU)
🥇 983
(162 MiB / 22.5% CPU)
954
(179 MiB / 41.9% CPU)
256 KiB HTTP/3 · QUIC HTTP/2 · TLS 847
(193 MiB / 51.2% CPU)
Not possible 706
(93 MiB / 36.1% CPU)
0
(165 MiB / 0.1% CPU)
🥇 948
(230 MiB / 46.3% CPU)
256 KiB HTTP/3 · QUIC HTTP/1 · TLS 🥇 1,090
(208 MiB / 45.0% CPU)
0
(peak 216 · 144 MiB / 21.9% CPU)
872
(96 MiB / 32.0% CPU)
0
(148 MiB / 0.2% CPU)
989
(245 MiB / 47.6% CPU)

On this GHA pass TWP÷YARP H1 TLS ≈ 1.23× (64 KiB) / 1.28× (256 KiB); H2→H1 ≈ 1.23× / 1.16×; H3→H1 ≈ 1.27× / 1.13×. TWP÷nginx H1 TLS ≈ 1.43 / 1.58. Absolute RPS swings by VM; prefer ratios.

Windows — POST 64 KiB request + 64 KiB response

Median of 3 repeats on windows-latest @ 8bfa7852. Source: Actions 35092838467 (compare-post).

Not possible: HAProxy and Envoy columns are omitted (no official Windows port).

Not possible: HAProxy and Envoy columns are omitted (no official Windows port).

Not possible: HAProxy and Envoy columns are omitted (no official Windows port).

Client Origin TWP nginx YARP
HTTP/1 · TLS HTTP/1 · plain 🥇 6,265
(98 MiB / 43.7% CPU)
361
(142 MiB / 24.7% CPU)
4,403
(137 MiB / 54.9% CPU)
HTTP/2 · TLS HTTP/1 · plain 🥇 4,552
(190 MiB / 48.0% CPU)
364
(144 MiB / 24.9% CPU)
2,959
(134 MiB / 38.4% CPU)
HTTP/3 · QUIC HTTP/1 · plain 🥇 2,026
(179 MiB / 39.5% CPU)
Not possible (no QUIC) 1,928
(218 MiB / 49.6% CPU)
HTTP/2 · plain HTTP/1 · plain 🥇 6,752
(189 MiB / 45.0% CPU)
1,799
(130 MiB / 24.7% CPU)
6,174
(123 MiB / 52.5% CPU)
HTTP/2 · TLS HTTP/2 · plain 8
(88 MiB / 0.2% CPU)
Not possible 🥇 3,734
(145 MiB / 47.7% CPU)
HTTP/2 · TLS HTTP/2 · TLS 8
(89 MiB / 0.1% CPU)
Not possible 🥇 2,795
(145 MiB / 46.3% CPU)
HTTP/3 · QUIC HTTP/2 · TLS 1,801
(180 MiB / 45.2% CPU)
Not possible 🥇 1,870
(209 MiB / 49.3% CPU)
HTTP/3 · QUIC HTTP/1 · TLS 🥇 1,930
(180 MiB / 41.5% CPU)
Not possible (no QUIC) 1,830
(221 MiB / 48.5% CPU)

TWP leads H1 POST (1.5× YARP), H2 POST (1.2× YARP), and H3 POST (~1.1× YARP).

Linux — POST 64 KiB request + 64 KiB response

Median of 3 repeats @ 8bfa7852. Source: Actions 35092838467 (compare-post).

Client Origin TWP nginx HAProxy Envoy YARP
HTTP/1 · TLS HTTP/1 · plain 4,706
(131 MiB / 45.2% CPU)
3,494
(100 MiB / 48.9% CPU)
4,766
(85 MiB / 41.1% CPU)
🥇 4,816
(133 MiB / 42.2% CPU)
3,114
(174 MiB / 55.3% CPU)
HTTP/2 · TLS HTTP/1 · plain 🥇 3,051
(210 MiB / 47.8% CPU)
1,296
(113 MiB / 21.6% CPU)
1,773
(82 MiB / 24.1% CPU)
0
(peak 2,797 · 142 MiB / 22.5% CPU)
2,483
(170 MiB / 48.6% CPU)
HTTP/3 · QUIC HTTP/1 · plain 🥇 2,881
(226 MiB / 44.1% CPU)
457
(109 MiB / 25.0% CPU)
2,078
(91 MiB / 35.9% CPU)
0
(125 MiB / 0.1% CPU)
2,552
(259 MiB / 49.6% CPU)
HTTP/2 · plain HTTP/1 · plain 🥇 5,393
(226 MiB / 44.3% CPU)
2,294
(97 MiB / 22.5% CPU)
2,629
(69 MiB / 23.7% CPU)
0
(peak 4,450 · 133 MiB / 23.6% CPU)
4,330
(160 MiB / 48.2% CPU)
HTTP/2 · TLS HTTP/2 · plain 2
(117 MiB / 0.1% CPU)
Not possible 1,363
(86 MiB / 24.4% CPU)
🥇 2,826
(141 MiB / 23.5% CPU)
2,367
(181 MiB / 47.3% CPU)
HTTP/2 · TLS HTTP/2 · TLS 8
(121 MiB / 0.3% CPU)
Not possible 1,048
(87 MiB / 24.5% CPU)
🥇 2,023
(147 MiB / 23.1% CPU)
1,880
(175 MiB / 46.6% CPU)
HTTP/3 · QUIC HTTP/2 · TLS 🥇 1,834
(240 MiB / 49.0% CPU)
Not possible 1,118
(95 MiB / 31.6% CPU)
0
(126 MiB / 0.1% CPU)
1,761
(255 MiB / 47.1% CPU)
HTTP/3 · QUIC HTTP/1 · TLS 🥇 2,088
(238 MiB / 44.9% CPU)
367
(120 MiB / 24.9% CPU)
1,492
(95 MiB / 32.4% CPU)
0
(126 MiB / 0.1% CPU)
1,944
(257 MiB / 47.9% CPU)

Linux nginx H1/H2/H3 POST completed (nginx.org mainline). TWP÷YARP H1 ≈ 1.5×; H2 ≈ 1.3×; H3 ≈ 1.1×. TWP÷nginx H3 ≈ 4×.

Windows — lossy / high-RTT (H2 HOL / H3 loss)

Userspace 5 ms one-way delay + 1% TCP connection stall (H1/H2) or UDP datagram drop (H3); 64 KiB GET. Median of 3 repeats on windows-latest @ 8bfa7852 — 35092841035 (compare-lossy).

Not possible: HAProxy and Envoy columns are omitted (no official Windows port). Not possible: HAProxy and Envoy columns are omitted (no official Windows port). Not possible: HAProxy and Envoy columns are omitted (no official Windows port).

Client Origin TWP nginx YARP
HTTP/1 · TLS HTTP/1 · plain 663
(112 MiB / 4.2% CPU)
653
(142 MiB / 16.7% CPU)
🥇 679
(123 MiB / 3.9% CPU)
HTTP/2 · TLS HTTP/1 · plain 0
(peak 89 · 121 MiB / 1.4% CPU)
0
(peak 17 · 142 MiB / 0.5% CPU)
0
(peak 16 · 100 MiB / 0.7% CPU)
HTTP/3 · QUIC HTTP/1 · plain 0
(67 MiB / 0.0% CPU)
Not possible (no QUIC) 0
(79 MiB / 0.0% CPU)
HTTP/2 · plain HTTP/1 · plain 0
(peak 88 · 131 MiB / 0.9% CPU)
0
(peak 17 · 128 MiB / 0.1% CPU)
0
(peak 16 · 91 MiB / 0.7% CPU)
HTTP/2 · TLS HTTP/2 · plain 0
(peak 8 · 67 MiB / 0.5% CPU)
Not possible 0
(peak 16 · 101 MiB / 0.9% CPU)
HTTP/2 · TLS HTTP/2 · TLS 0
(peak 9 · 72 MiB / 0.3% CPU)
Not possible 0
(peak 15 · 100 MiB / 0.6% CPU)
HTTP/3 · QUIC HTTP/2 · TLS 0
(71 MiB / 0.0% CPU)
Not possible 0
(80 MiB / 0.0% CPU)
HTTP/3 · QUIC HTTP/1 · TLS 0
(69 MiB / 0.0% CPU)
Not possible (no QUIC) 0
(79 MiB / 0.0% CPU)

TWP H2 HOL leads (~3.31× YARP). H3 is the protocol-shape win vs H2 HOL on the same lossy session; Win H3 GHA remains 0 (laptop re-measure kept above).

Linux — lossy / high-RTT (H2 HOL / H3 loss)

Median of 3 repeats @ 8bfa7852. Source: 35092841035 (compare-lossy; lossy H3 uses quic-http3).

Client Origin TWP nginx HAProxy Envoy YARP
HTTP/1 · TLS HTTP/1 · plain 1,214
(148 MiB / 10.2% CPU)
🥇 1,219
(102 MiB / 8.2% CPU)
1,218
(83 MiB / 4.8% CPU)
1,209
(128 MiB / 6.6% CPU)
1,211
(146 MiB / 13.1% CPU)
HTTP/2 · TLS HTTP/1 · plain 🥇 312
(186 MiB / 5.2% CPU)
40
(101 MiB / 0.2% CPU)
40
(84 MiB / 0.2% CPU)
40
(137 MiB / 0.3% CPU)
40
(129 MiB / 1.1% CPU)
HTTP/3 · QUIC HTTP/1 · plain 342
(158 MiB / 10.4% CPU)
100
(112 MiB / 1.8% CPU)
60
(86 MiB / 2.7% CPU)
🥇 1,578
(140 MiB / 20.3% CPU)
321
(178 MiB / 15.2% CPU)
HTTP/2 · plain HTTP/1 · plain 🥇 337
(177 MiB / 5.2% CPU)
40
(78 MiB / 0.1% CPU)
41
(67 MiB / 0.1% CPU)
40
(127 MiB / 0.3% CPU)
41
(123 MiB / 1.0% CPU)
HTTP/2 · TLS HTTP/2 · plain 0
(peak 16 · 97 MiB / 0.5% CPU)
Not possible 🥇 42
(90 MiB / 0.3% CPU)
40
(136 MiB / 0.2% CPU)
41
(133 MiB / 1.0% CPU)
HTTP/2 · TLS HTTP/2 · TLS 0
(peak 13 · 98 MiB / 0.5% CPU)
Not possible 🥇 41
(84 MiB / 0.4% CPU)
40
(138 MiB / 0.4% CPU)
41
(131 MiB / 1.2% CPU)
HTTP/3 · QUIC HTTP/2 · TLS 325
(143 MiB / 19.3% CPU)
Not possible 66
(91 MiB / 3.2% CPU)
🥇 1,459
(145 MiB / 23.4% CPU)
349
(190 MiB / 20.2% CPU)
HTTP/3 · QUIC HTTP/1 · TLS 325
(165 MiB / 10.9% CPU)
99
(118 MiB / 1.9% CPU)
63
(90 MiB / 3.1% CPU)
🥇 1,456
(141 MiB / 22.1% CPU)
350
(185 MiB / 18.6% CPU)

TWP H2 HOL ≫ YARP (~7.7×). H3 TWP÷YARP ≈ 1×.

Architecture-sensitive

These runs isolate slow app readers, origin-early response, HTTP/2 duplex, and WebSocket echo. See TWP vs YARP IO model. Laptop 1-rep numbers are on Performance Local Lab.

Median of 3 repeats on matched 4 vCPU / 16 GiB runners @ 8bfa7852 (35092846209). Slow consumer = 256 KiB GET, 16 KiB read + 8 ms sleep. Early response = 64 KiB POST, origin writes after 8 KiB. Duplex HTTP/2 = overlapping 64 KiB POST on H2 TLS↔H2 TLS. WebSocket row = H1 Upgrade echo round-trips/sec (not RFC 8441; see WebSocket RFC 8441 table below).

Lossy-link runs (slow network) are already published above; they are not a slow app reader.

Windows

Not possible: HAProxy and Envoy columns are omitted (no official Windows port).

Scenario Client Origin TWP nginx YARP
Slow consumer (256 KiB GET, throttled client read) HTTP/1 · TLS HTTP/1 · plain 🥇 248
(100 MiB / 4.9% CPU)
192
(143 MiB / 24.7% CPU)
240
(111 MiB / 4.6% CPU)
Slow consumer (256 KiB GET, throttled client read) HTTP/2 · TLS HTTP/1 · plain 248
(121 MiB / 4.6% CPU)
180
(142 MiB / 24.7% CPU)
🥇 253
(112 MiB / 6.7% CPU)
Slow consumer (256 KiB GET, throttled client read) HTTP/3 · QUIC HTTP/1 · plain 273
(102 MiB / 15.2% CPU)
Not possible (no QUIC) 🥇 274
(162 MiB / 15.7% CPU)
Early response (origin writes after first request chunk) HTTP/1 · TLS HTTP/1 · plain 🥇 11,064
(101 MiB / 41.4% CPU)
679
(143 MiB / 24.9% CPU)
7,558
(138 MiB / 53.7% CPU)
Early response (origin writes after first request chunk) HTTP/2 · TLS HTTP/1 · plain 2,870
(181 MiB / 40.4% CPU)
0
(peak 343 · 144 MiB / 24.9% CPU)
🥇 3,336
(135 MiB / 51.9% CPU)
Early response (origin writes after first request chunk) HTTP/3 · QUIC HTTP/1 · plain 🥇 2,141
(149 MiB / 41.8% CPU)
Not possible (no QUIC) 1,888
(199 MiB / 52.7% CPU)
Slow consumer (256 KiB GET, throttled client read) HTTP/2 · plain HTTP/1 · plain 248
(106 MiB / 3.9% CPU)
248
(127 MiB / 8.7% CPU)
🥇 256
(104 MiB / 4.3% CPU)
Slow consumer (256 KiB GET, throttled client read) HTTP/2 · TLS HTTP/2 · TLS 0
(peak 8 · 72 MiB / 0.3% CPU)
Not possible 🥇 256
(141 MiB / 4.9% CPU)
Early response (origin writes after first request chunk) HTTP/2 · TLS HTTP/2 · TLS 0
(97 MiB / 0.1% CPU)
Not possible 0
(123 MiB / 0.2% CPU)
Duplex (both directions live) HTTP/2 · TLS HTTP/2 · TLS 0
(95 MiB / 0.1% CPU)
Not possible 0
(114 MiB / 0.2% CPU)
Duplex (WebSocket / H1 Upgrade) HTTP/1 · TLS HTTP/1 · plain 🥇 66,034
(97 MiB / 41.3% CPU)
36,248
(143 MiB / 24.6% CPU)
61,591
(89 MiB / 44.1% CPU)

Linux

Scenario Client Origin TWP nginx HAProxy Envoy YARP
Slow consumer (256 KiB GET, throttled client read) HTTP/1 · TLS HTTP/1 · plain 468
(125 MiB / 9.2% CPU)
416
(101 MiB / 9.4% CPU)
🥇 472
(84 MiB / 5.8% CPU)
469
(139 MiB / 6.2% CPU)
419
(145 MiB / 14.0% CPU)
Slow consumer (256 KiB GET, throttled client read) HTTP/2 · TLS HTTP/1 · plain 473
(157 MiB / 12.2% CPU)
427
(102 MiB / 9.4% CPU)
474
(84 MiB / 5.4% CPU)
🥇 480
(157 MiB / 5.0% CPU)
474
(148 MiB / 16.2% CPU)
Slow consumer (256 KiB GET, throttled client read) HTTP/3 · QUIC HTTP/1 · plain 🥇 480
(135 MiB / 31.0% CPU)
0
(peak 347 · 124 MiB / 18.5% CPU)
479
(90 MiB / 7.8% CPU)
1
(156 MiB / 0.2% CPU)
476
(196 MiB / 37.0% CPU)
Early response (origin writes after first request chunk) HTTP/1 · TLS HTTP/1 · plain 6,746
(148 MiB / 44.2% CPU)
5,410
(101 MiB / 48.0% CPU)
🥇 7,255
(84 MiB / 39.9% CPU)
0
(peak 673 · 130 MiB / 6.6% CPU)
4,645
(176 MiB / 55.1% CPU)
Early response (origin writes after first request chunk) HTTP/2 · TLS HTTP/1 · plain 2,465
(210 MiB / 48.0% CPU)
0
(peak 858 · 112 MiB / 15.2% CPU)
🥇 2,509
(85 MiB / 24.7% CPU)
0
(peak 2,574 · 145 MiB / 23.1% CPU)
2,226
(171 MiB / 48.6% CPU)
Early response (origin writes after first request chunk) HTTP/3 · QUIC HTTP/1 · plain 🥇 4,647
(224 MiB / 46.4% CPU)
0
(peak 706 · 122 MiB / 24.5% CPU)
2,866
(93 MiB / 32.9% CPU)
0
(126 MiB / 0.1% CPU)
3,107
(258 MiB / 47.4% CPU)
Slow consumer (256 KiB GET, throttled client read) HTTP/2 · plain HTTP/1 · plain 475
(139 MiB / 14.4% CPU)
463
(79 MiB / 11.5% CPU)
🥇 476
(68 MiB / 6.2% CPU)
472
(150 MiB / 4.5% CPU)
474
(149 MiB / 14.7% CPU)
Slow consumer (256 KiB GET, throttled client read) HTTP/2 · TLS HTTP/2 · TLS 9
(96 MiB / 1.8% CPU)
Not possible 447
(90 MiB / 12.9% CPU)
470
(157 MiB / 9.3% CPU)
🥇 470
(172 MiB / 21.4% CPU)
Early response (origin writes after first request chunk) HTTP/2 · TLS HTTP/2 · TLS 0
(117 MiB / 0.1% CPU)
Not possible 🥇 8
(95 MiB / 0.2% CPU)
0
(peak 2,844 · 152 MiB / 19.7% CPU)
0
(141 MiB / 0.1% CPU)
Duplex (both directions live) HTTP/2 · TLS HTTP/2 · TLS 0
(118 MiB / 0.1% CPU)
Not possible 0
(93 MiB / 0.1% CPU)
0
(peak 2,526 · 156 MiB / 17.2% CPU)
0
(146 MiB / 0.2% CPU)
Duplex (WebSocket / H1 Upgrade) HTTP/1 · TLS HTTP/1 · plain 45,832
(128 MiB / 44.4% CPU)
🥇 49,425
(102 MiB / 36.9% CPU)
48,657
(82 MiB / 39.8% CPU)
46,062
(127 MiB / 41.2% CPU)
41,388
(126 MiB / 45.3% CPU)

Slow consumer is sleep-bound; H1/H2/H3 sit in the same band. Early-response H1/H2/H3: TWP leads (H1 early ≈ 2.00× / 1.47× YARP Win/Linux). Duplex H2: YARP leads by design — Win ≈ 0.59× (1,270 / 2,135), Linux ≈ 0.15× (282 / 1,882); irreducible concurrent-copier cell (see IO model). WebSocket: TWP÷YARP Windows ≈ 1.06×; Linux nginx leads.

TLS termination cost (H1 TLS → cleartext origin)

Isolates keep-alive tiny GET vs new connection per request (handshake-dominated) vs keep-alive 256 KiB. Product comparison uses RPS and end-to-end latency; TWP can also capture ClientTlsTiming when TWP_RPS_CAPTURE_TLS=1 (child process) — nginx/YARP have no equivalent hook.

Windows

Median of 3 repeats on windows-latest @ 8bfa7852. Source: Actions 35092843724. Absolute RPS on GHA swings hard; prefer TWP÷YARP.

Not possible: HAProxy and Envoy columns are omitted (no official Windows port).

Workload TWP nginx YARP
Keep-alive · tiny GET 🥇 21,760
(85 MiB / 49.0% CPU)
9,611
(142 MiB / 24.8% CPU)
19,339
(101 MiB / 48.2% CPU)
New-connection · tiny GET 🥇 747
(89 MiB / 9.4% CPU)
0
(peak 247 · 140 MiB / 24.2% CPU)
732
(113 MiB / 9.5% CPU)
Keep-alive · 256 KiB GET 🥇 2,948
(133 MiB / 45.9% CPU)
0
(peak 158 · 143 MiB / 24.5% CPU)
2,718
(128 MiB / 45.9% CPU)

Linux

Median of 3 repeats @ 8bfa7852. Source: Actions 35092843724.

Workload TWP nginx HAProxy Envoy YARP
Keep-alive · tiny GET 23,990
(112 MiB / 50.2% CPU)
28,472
(100 MiB / 40.9% CPU)
🥇 28,484
(83 MiB / 43.2% CPU)
17,372
(127 MiB / 58.6% CPU)
20,581
(136 MiB / 50.5% CPU)
New-connection · tiny GET 976
(116 MiB / 47.4% CPU)
1,017
(100 MiB / 44.5% CPU)
956
(82 MiB / 44.1% CPU)
🥇 1,072
(129 MiB / 41.4% CPU)
967
(152 MiB / 46.4% CPU)
Keep-alive · 256 KiB GET 2,708
(128 MiB / 36.8% CPU)
1,740
(100 MiB / 53.7% CPU)
🥇 2,966
(84 MiB / 33.2% CPU)
2,734
(146 MiB / 34.2% CPU)
2,145
(172 MiB / 45.3% CPU)

All three workloads are >1.00× YARP on both OS. nginx leads Linux keep-alive tiny and Linux new-connection; TWP is second, YARP third.

Unary gRPC (H2 TLS)

Unary Echo RPC/s @ c=64 over H2 TLS→H2 TLS for Titanium, YARP, nginx (grpc_pass), HAProxy, and Envoy (OS-possible peers only). Not folded into the architecture-sensitive tables. Median of 3 repeats @ 8bfa7852 — 35092856793.

OS Titanium YARP nginx HAProxy Envoy
Windows 111,791
(116 MiB / 22.8% CPU)
63,757
(120 MiB / 41.9% CPU)
0
(143 MiB / 24.9% CPU)
Not possible Not possible
Linux 78,834
(121 MiB / 32.5% CPU)
45,952
(149 MiB / 42.2% CPU)
0
(131 MiB / 25.1% CPU)
18,339
(83 MiB / 24.2% CPU)
30,733
(127 MiB / 21.4% CPU)
macOS 18,711
(97 MiB / 24.0% CPU)
13,574
(137 MiB / 34.5% CPU)
0
(61 MiB / 3.1% CPU)
0
(63 MiB / 18.4% CPU)
7,199
(80 MiB / 20.7% CPU)

Unary gRPC (H2 TLS → h2c)

Unary Echo RPC/s @ c=64 over H2 TLS → h2c (edge TLS, cleartext H2 origin). Peers: Titanium, YARP, HAProxy, Envoy. Mode: compare-grpc (*-grpc-h2c). Median of 3 repeats @ 8bfa7852 — 35092859116.

Not possible: nginx column omitted (no H2 upstream).

OS Titanium YARP HAProxy Envoy
Windows 60,626
(93 MiB / 24.4% CPU)
34,219
(117 MiB / 47.2% CPU)
Not possible Not possible
Linux 43,638
(126 MiB / 28.5% CPU)
24,134
(169 MiB / 43.3% CPU)
7,783
(82 MiB / 24.4% CPU)
12,047
(128 MiB / 22.2% CPU)
macOS 24,524
(95 MiB / 24.8% CPU)
16,722
(130 MiB / 35.8% CPU)
0
(65 MiB / 17.4% CPU)
0
(79 MiB / 20.6% CPU)

WebSocket (H1 TLS → H1 TLS)

WebSocket echo round-trips/sec over dual-TLS H1 (proxy_ssl style). Mode: compare-ws-h1tls (*-duplex-ws-h1tls).

OS Titanium YARP nginx HAProxy Envoy
Windows 66,023
(102 MiB / 42.5% CPU)
63,442
(90 MiB / 46.5% CPU)
31,084
(143 MiB / 24.7% CPU)
Not possible Not possible
Linux 38,814
(137 MiB / 44.3% CPU)
34,209
(136 MiB / 45.8% CPU)
41,105
(108 MiB / 38.2% CPU)
42,059
(85 MiB / 39.8% CPU)
40,348
(127 MiB / 40.1% CPU)
macOS 10,520
(144 MiB / 33.3% CPU)
8,988
(145 MiB / 33.6% CPU)
10,184
(81 MiB / 26.4% CPU)
10,985
(67 MiB / 32.0% CPU)
15,732
(81 MiB / 30.8% CPU)

WebSocket (H2 TLS 8441 → H1)

WebSocket echo over RFC 8441 extended CONNECT (H2 TLS client → H1 plain origin). Mode: compare-ws-h2 (*-duplex-ws-h2).

Not possible: nginx column omitted (no RFC 8441 extended CONNECT reverse).

OS Titanium YARP HAProxy Envoy
Windows 23,244
(172 MiB / 41.7% CPU)
0
(165 MiB / 19.8% CPU)
Not possible Not possible
Linux 1,530
(143 MiB / 16.9% CPU)
0
(172 MiB / 25.2% CPU)
1,535
(82 MiB / 5.4% CPU)
0
(123 MiB / 0.3% CPU)
macOS 4,262
(219 MiB / 29.2% CPU)
0
(86 MiB / 12.1% CPU)
4,087
(66 MiB / 35.2% CPU)
0
(73 MiB / 0.6% CPU)

Other measurements

What Result
HTTPS TTFB vs direct (median, 14 hosts) Cold ≈ parity (−1 ms); warm −25 ms (proxy faster)
HTTP/1 loopback GET (no body intercept) ~128 µs, ~9.9 KB allocated / request
Basic example footprint (Release, after load) ~74 MB working set · ~24–29 MB private bytes
dotnet run -c Release --project benchmarks/Titanium.Web.Proxy.Benchmarks -- --filter '*Throughput*'

Local laptop BDN @ 9d7c2966 (Release):

Benchmark Setup Mean Allocated / op
HTTP/1 GET through proxy Passthrough 128 µs 9.9 KB
HTTP/2 multiplexed GETs 10 concurrent streams 253 µs / batch ~4.4 KB / request

Raising limits on large hosts

There is no artificial upper clamp on server defaults. Per-endpoint overrides:

Knob Scope Default Override
ProxyServer.MaxCachedConnections process, per upstream host 128 any ≥ 1
ProxyEndPoint.MaxCachedConnections endpoint → pool depth for that EP’s sessions null (use server) e.g. 256 on reverse EP
ProxyEndPoint.MaxConcurrentClients endpoint admission null (off) any ≥ 1
ResourceLimits.MaxConcurrentStreamsPerConnection H2 streams 256 ProxyResourceLimits.Create(...)
TransparentQuicProxyEndPoint.MaxInboundBidirectionalStreams H3 100 (probe uses 256) property on EP
ForwardCleartext transparent TLS terminate false true + decrypt
proxy.MaxCachedConnections = 512;
proxy.ResourceLimits = ProxyResourceLimits.Create(
    /* … */,
    maxConcurrentStreamsPerConnection: 1000,
    maxCachedConnectionsPerHost: 512,
    /* … */);

var ep = new TransparentProxyEndPoint(IPAddress.Any, 443, decryptSsl: true)
{
    ForwardHost = "127.0.0.1",
    ForwardPort = 8080,
    ForwardCleartext = true,
    MaxCachedConnections = 256,
    GenericCertificateName = "example.com"
};
ep.BeforeSslAuthenticate += (_, a) =>
{
    a.UpstreamHttpProtocol = UpstreamHttpProtocol.Http11;
    a.AllowHttpProtocolTranslation = true; // HTTP/2 client → HTTP/1 origin
    return Task.CompletedTask;
};

Maintainer notes

CI cadence, shards, paste scripts, and gate floors for people refreshing these tables. Consumers can skip this section.

Tiered cadence

Tier Mode When
Daily / per-PR compare-spot minutes
Milestone compare-terminate / compare-matrix ~1–2h
Editions compare-editions ~60 min (CLI / Plus / Intercept stress arms)
Cross-version (Gate 2) compare-cross-version ~1–2h vs committed 6.0 baselines
Pre-wiki smoke compare-product-smoke (Linux 2 shards, repeats=1) ~30–60 min; required before full product
Release / wiki compare-product (3 comparison-group shards × Win/Linux/mac) ~2–2½h wall (Free account queues beyond 20 jobs)
Unary gRPC compare-grpc Win/Linux/mac; H2↔H2 + H2→h2c (arm_shard 1/2, 2/2)
WebSocket dual-TLS compare-ws-h1tls Win/Linux/mac; H1 TLS→H1 TLS echo
WebSocket RFC 8441 compare-ws-h2 Win/Linux/mac; H2 TLS→H1 plain (nginx N/A)
Heavier tables compare-bodies (2 shards) / post / lossy / arch (3 shards) / tls-cost dispatch independently

See PERF-GATES.md.

Arm shards (comparison groups)

--arm-shard i/n (workflow input arm_shard) partitions wiki rows (Client×Origin + heavier/arch workload suffix), not individual proxy arms. Paste unions shard CSVs (paste-compare-product-wiki.ps1 -RunIds …; heavier RUNS lists). Table “Source: Actions” may list several run URLs for one table — do not mix SHAs. Free GitHub accounts allow 20 concurrent jobs (~34 for a full suite); extras queue, they do not fail. Dispatch product (and cross-version) first when wall clock matters.

One wiki row = one GHA job’s Client×Origin cell set: TWP + YARP + nginx + HAProxy + Envoy (when the OS can run them) + TWP Lite + Full stay on the same VM. Shards split rows, not individual proxies — so TWP÷YARP and Lite÷Reverse remain same-job ratios. Do not compare absolute RPS across shards (different VMs).

Gate thresholds

  • Reverse product signal: TWP÷YARP ≥ 0.75 (nginx / HAProxy / Envoy are wiki and chart peers only — no CI gate). Edition CLI/Plus ratios floor at 0.50.
  • MITM overhead: Lite÷Reverse ≥ 0.50 and Full÷Reverse ≥ 0.50 (median of 3 GHA runs @ c=64). Absolute RPS moves with runner heat; ratios are the claim.
  • Editions: see PERF-GATES.md and validate-edition-gates.ps1.
  • Cross-version (Gate 2) before a major tag: run compare-cross-version (reverse matrix, routes unset) on develop vs committed 6.0 baselines (baseline-6.0-win.csv / baseline-6.0-linux.csv).
Gate Threshold
Peer-normalized RPS (when YARP peer exists) (TWP÷YARP)_7 ÷ (TWP÷YARP)_6 ≥ 0.90 or current (TWP÷YARP) ≥ 0.90
Absolute RPS floor (TWP arms) 7.0 ÷ 6.0 ≥ 0.70 (runner heat — peers move with the box)
RSS 7.0 ÷ 6.0 ≤ 1.20 per TWP arm @ c=64

nginx/YARP absolute RPS is not gated. See validate-cross-version.ps1.

pwsh tools/RpsLoadProbe/run-rps.ps1 -Mode compare-cross-version
pwsh tools/RpsLoadProbe/validate-cross-version.ps1 `
  -BaselineCsv tools/RpsLoadProbe/results/baseline-6.0-win.csv `
  -CurrentCsv  tools/RpsLoadProbe/results/rps-ramp-*.csv

Paste / regenerate

Product refresh and heavier tables:

pwsh tools/RpsLoadProbe/run-rps.ps1 -Mode compare-product
pwsh tools/RpsLoadProbe/run-rps.ps1 -Mode compare-editions
pwsh tools/RpsLoadProbe/validate-edition-gates.ps1 -CsvPath tools/RpsLoadProbe/results/rps-ramp-*.csv
pwsh tools/RpsLoadProbe/run-rps.ps1 -Mode compare-bodies
pwsh tools/RpsLoadProbe/run-rps.ps1 -Mode compare-post
pwsh tools/RpsLoadProbe/run-rps.ps1 -Mode compare-lossy
pwsh tools/RpsLoadProbe/run-rps.ps1 -Mode compare-tls-cost
pwsh tools/RpsLoadProbe/run-rps.ps1 -Mode compare-arch
pwsh tools/RpsLoadProbe/run-rps.ps1 -Mode compare-saturation

Harness details: RpsLoadProbe. The harness does not disable TWP safety that peers also skip, and it does not retune to pass gates (PERF-GATES.md). MITM leaf keys are a shared RSA/ECDSA pair per CertificateManager (intentional RPS tradeoff).

Clone this wiki locally