Skip to content

proxygen / proxygen-coro: shared source tree + performance work - #1435

Draft
SUJP123 wants to merge 5 commits into
MDA2AV:mainfrom
SUJP123:proxygen-engines-coalesced
Draft

proxygen / proxygen-coro: shared source tree + performance work#1435
SUJP123 wants to merge 5 commits into
MDA2AV:mainfrom
SUJP123:proxygen-engines-coalesced

Conversation

@SUJP123

@SUJP123 SUJP123 commented Sep 3, 2026

Copy link
Copy Markdown

Draft. Coalesces #1097 (@lnicco) with the some refactoring work, plus optimization on top.

Both entries build from one source tree (frameworks/proxygen/src, selected by a TARGET build arg — same pattern as sark-h3sark).

Static files are read per request and follow the disk; the precompressed .br/.gz siblings are selected off Accept-Encoding, which removes the on-the-fly gzip of every CSS/JS/HTML response. Response compression is scoped to application/json.

validate.sh: 82 passed, 0 failed on both entries.

lnicco and others added 3 commits September 3, 2026 11:35
Add a pinned, non-root Proxygen image with HTTP/1.1, TLS, h2c,
HTTP/2, HTTP/3, static, JSON, upload, and RFC 6455 WebSocket support
across 18 benchmark profiles.
Add a pinned, non-root Proxygen coroutine image using
proxygen::coro::HTTPHandler and HTTPSourceHolder across the same 18
HTTP/1.1, TLS, h2c, HTTP/2, HTTP/3, static, JSON, upload, and
WebSocket profiles.
…st cost

Builds on the two Proxygen engine commits. Both entries now build from
frameworks/proxygen/src selected by a TARGET build arg, the way sark-h3 reuses
sark, so a fix lands in both entries at once.

Static assets and their precompressed .br/.gz siblings are read once at startup
and served as non-owning IOBuf views: no disk I/O, no per-request compression,
no copy, no payload allocation. This replaces an open/read plus an on-the-fly
gzip of every CSS/JS/HTML response, which dominated the static profiles.

Also:
- shared RFC 6455 codec: frames unmasked in place, one egress write per read
- response compression scoped to application/json, the type json-comp scores
- coro attaches CompressionFilter per response instead of registering a
  server-level factory, which allocated four objects on every request because
  HTTPFilterFactoryHandler builds filters before reading request headers
- per-request allocations removed from the hot path: getPathAsStringPiece, a
  query-string scan instead of the parsed parameter map, string_view content
  types, to_chars, and no shared_ptr copy per handler
- mimalloc preloaded; separate --threads / --h3_threads
- base image pinned by digest for reproducible rounds

Measured locally on a 32-core cpuset with wrk, so relative deltas only:

  static      13,012 -> 1,049,630 rps    static-tls  12,701 -> 706,558 rps
  json        +38%                       json-comp   +41% classic / +82% coro
  baseline    +7.5% classic / +17% coro  websocket   -30% / -46% CPU per frame

Peak memory on static at 6800 connections drops 2.1 GiB -> 160 MiB.

validate.sh reports 63/63 for both entries; HTTP/3 and RFC 6455 conformance
checked separately.
@SUJP123 SUJP123 changed the title proxygen / proxygen-coro: shared source tree + performance work (draft) proxygen / proxygen-coro: shared source tree + performance work Sep 3, 2026
Rebased onto current main, which changed two things under this branch.

The static rules now require served bytes to follow the disk and exclude a
cache assembled in the entry ('no reading the directory into a map at
startup'), for engine entries too. validate.sh enforces it with a staleness
probe that swaps the file under a running server. The startup-preloaded asset
table failed both probes, so static is back to a per-request read: one open,
one fstat, one readFull into the response buffer.

Serving the precompressed .br/.gz siblings is still allowed by selecting the
variant off Accept-Encoding, so the on-the-fly gzip of every CSS/JS/HTML
response stays gone -- that was the dominant cost.

Also drops the json, static and upload subscriptions: all three profiles were
removed from the arena (MDA2AV#1375, MDA2AV#1374, MDA2AV#1382). The handlers stay, since
json-tls/json-comp/json-h2c and static-tls/static-h2/static-h3 still use them.
@SUJP123
SUJP123 force-pushed the proxygen-engines-coalesced branch from 1d8165a to d51787b Compare September 3, 2026 18:54
@SUJP123

SUJP123 commented Sep 3, 2026

Copy link
Copy Markdown
Author

/benchmark-multiple -f proxygen,proxygen-coro

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

👋 Benchmark request received. A collaborator will review and approve the run.

@SUJP123

SUJP123 commented Sep 3, 2026

Copy link
Copy Markdown
Author

Wanted to benchmark these and see if results are lining up as expected before taking out of draft if thats cool.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results

Frameworks: 2 | Test: all tests

proxygen

Test Conn RPS CPU Mem Δ RPS Δ Mem
baseline 4096 2,123,494 6408.5% 133MiB ~0% ~0%
pipelined 4096 1,837,125 6478.5% 158MiB ~0% ~0%
limited-conn 4096 1,094,737 5898.3% 84MiB ~0% ~0%
json-comp 4096 241,288 6242.4% 1.8GiB ~0% ~0%
json-comp 16384 205,525 6162.7% 2.5GiB ~0% ~0%
json-tls 4096 658,578 6419.9% 209MiB ~0% ~0%
static-tls 1024 574,684 6436.9% 201MiB ~0% ~0%
baseline-h2 256 5,507,698 6322.9% 111MiB ~0% ~0%
baseline-h2 1024 5,450,849 6260.4% 287MiB ~0% ~0%
static-h2 256 596,398 6400.2% 287MiB ~0% ~0%
static-h2 1024 595,832 6098.3% 884MiB ~0% ~0%
baseline-h2c 256 5,983,697 6425.9% 105MiB ~0% ~0%
baseline-h2c 1024 5,675,603 6358.5% 276MiB ~0% ~0%
baseline-h2c 4096 5,357,033 6025.5% 911MiB ~0% ~0%
json-h2c 1024 1,071,357 6375.8% 352MiB ~0% ~0%
json-h2c 4096 1,020,794 5979.3% 1.2GiB ~0% ~0%
baseline-h3 64 1,793,628 4145.8% 516MiB ~0% ~0%
static-h3 64 318,906 4812.3% 417MiB ~0% ~0%
echo-ws 512 3,171,334 6452.9% 71MiB ~0% ~0%
echo-ws 4096 3,337,572 6422.6% 127MiB ~0% ~0%
echo-ws 16384 3,161,912 5905.3% 188MiB ~0% ~0%
echo-ws-pipeline 512 48,604,540 6683.0% 70MiB ~0% ~0%
echo-ws-pipeline 4096 50,268,531 6128.4% 123MiB ~0% ~0%
echo-ws-pipeline 16384 48,893,568 6267.5% 184MiB ~0% ~0%
echo-ws-limited 512 981,657 4407.8% 69MiB ~0% ~0%
echo-ws-limited 4096 1,059,368 4667.4% 70MiB ~0% ~0%

proxygen-coro

Test Conn RPS CPU Mem Δ RPS Δ Mem
baseline 4096 1,592,904 6412.9% 164MiB ~0% ~0%
pipelined 4096 1,654,631 6518.6% 189MiB ~0% ~0%
limited-conn 4096 1,047,692 6382.8% 130MiB ~0% ~0%
json-comp 4096 263,070 6326.7% 194MiB ~0% ~0%
json-comp 16384 261,322 6181.7% 341MiB ~0% ~0%
json-tls 4096 623,934 6363.2% 205MiB ~0% ~0%
static-tls 1024 562,882 6375.9% 181MiB ~0% ~0%
baseline-h2 256 5,046,401 6262.3% 134MiB ~0% ~0%
baseline-h2 1024 4,318,693 6426.9% 300MiB ~0% ~0%
static-h2 256 561,764 6237.4% 219MiB ~0% ~0%
static-h2 1024 572,571 5931.7% 534MiB ~0% ~0%
baseline-h2c 256 5,319,721 6358.1% 135MiB ~0% ~0%
baseline-h2c 1024 4,411,960 6369.0% 314MiB ~0% ~0%
baseline-h2c 4096 3,915,049 6001.4% 878MiB ~0% ~0%
json-h2c 1024 1,065,053 6367.7% 278MiB ~0% ~0%
json-h2c 4096 1,008,490 6049.0% 749MiB ~0% ~0%
baseline-h3 64 2,244,496 4264.7% 194MiB ~0% ~0%
static-h3 64 318,521 4345.5% 350MiB ~0% ~0%
echo-ws 512 1,886,406 6682.7% 83MiB ~0% ~0%
echo-ws 4096 2,054,448 6291.9% 170MiB ~0% ~0%
echo-ws 16384 1,801,511 6609.5% 340MiB ~0% ~0%
echo-ws-pipeline 512 28,620,716 6689.0% 80MiB ~0% ~0%
echo-ws-pipeline 4096 31,401,961 6356.2% 170MiB ~0% ~0%
echo-ws-pipeline 16384 28,490,064 6208.2% 331MiB ~0% ~0%
echo-ws-limited 512 1,030,163 6214.9% 98MiB ~0% ~0%
echo-ws-limited 4096 1,018,019 6177.5% 113MiB ~0% ~0%

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