Skip to content

perf(http2): use static HPACK names for request headers - #37

Merged
hatoo merged 1 commit into
masterfrom
codex/perf-h2-static-header-names-20261021
Oct 21, 2026
Merged

hatoo merged 1 commit into
masterfrom
codex/perf-h2-static-header-names-20261021

Conversation

@hatoo

@hatoo hatoo commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Standard user headers currently spell out their names in every reusable HTTP/2 request block. Use the RFC 7541 static-table name reference while retaining the caller's plain value, order, duplicates and literal-without-indexing semantics. Unknown names remain literal. A representative eight-header block becomes 151 bytes instead of 235, saving 84 bytes on every request without per-request encoder work.

Three alternating counted pairs against a fixed Node 20.20.2/nghttp2 1.61.0 decoding peer gain 32.91% median RPS. A separate reversed-order confirmation with twice as many requests gains 33.29%. All six pairs improve (29.61–37.86%); server CPU/request falls 24.84% in both series. Mean latency falls 24.73%/24.94% and p99 falls 26.79%/38.41%. This claim is specific to the eight-header decoding workload.

  • Baseline b8766f9; Rust 1.99.1, default production features, consistent fat LTO/one codegen unit, independently frozen --bin shb builds. WSL2/Ryzen 9 3950X, client CPU 8, server CPU 0; 16 connections × 64 streams. 32,768 warmups/variant, then 131,072 requests/sample (confirmation 262,144).
  • All 5,046,272 Node responses across acceptance and guard/stress workloads match the peer's decoded count exactly, with verified values, zero errors, closed sessions, and exact per-request byte savings. Fixed hfast comparisons also observe +10.19%/+6.95% for the common-header workload; it does not decode HPACK, so those are supporting wire/copy observations.
  • Ordinary Node GETs have +0.06% median RPS; unknown names -2.42%, both with identical bytes and mixed pairs. Short H3 guards were unstable (-8.71%/+2.68%); a single duration correction to about eight seconds/sample gives +10.04%, all three positive. No H3 gain or consistent regression is established. All 181,665,792 comparison/guard responses including warmups have zero errors. No timestamp, sample, status, error or request-accounting code changes.
  • Debug and release each pass 513 unit + 62 integration tests; strict all-target Clippy and rustfmt pass. Independent python-hpack/hyper-h2 checks 453 blocks/all 52 names and 17 live cases/544 responses per binary, including duplicate/empty/UTF-8 fields, large CONTINUATION blocks, table-size zero, POST bodies and exact transport-byte accounting. A wrong-static-index mutation is rejected.

CI now runs the independent oracle with pinned versions. Reproducible counted peer/driver, complete methodology, workload JSON, limitations and all guard results are in benchmarks/h2-static-header-names.md. Raw measurements remain in local shb/optimization-results/c178/; no large artifacts are committed. HTTP/1 and HTTP/3 encoders are unchanged; this does not resolve historical QUIC loss-recovery limitations.

@hatoo
hatoo enabled auto-merge (squash) October 21, 2026 09:14
@hatoo
hatoo merged commit 55611fc into master Oct 21, 2026
4 checks passed
@hatoo
hatoo deleted the codex/perf-h2-static-header-names-20261021 branch October 21, 2026 09:21
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.

1 participant