http,net,stream: reconcile read, write, and parser paths
This PR reconciles the overlapping goals of #64887, #64346, #64393, and
#64455 into one canonical HTTP, net, and stream architecture.
Those PRs identified real bottlenecks and directly informed this work. The
goal here is to combine their valid objectives without landing competing
response builders, caches, fast paths, or duplicate lifecycle state.
No public API or documented wire behavior is intentionally changed.
Changes
790260a488e — canonical write architecture
- batches compatible HTTP framing, payloads, trailers, and terminating chunks
through one shared vector path; - fixes corked-output ordering while preserving callbacks, backpressure,
destruction, TLS, trailers, and pipelining; - creates
WriteWrapobjects only for asynchronous writes; - coalesces adjacent native string storage safely;
- preserves partial writes, errors, IPC, async hooks, and custom transports;
- caches
maxHeaderPairsonce per independent parser header section.
bb58fcd9904 — final path reconciliation
- reuses the existing send path for eligible final strings, Buffers, and
Uint8Arrayvalues; - preserves mutable Buffer and custom
write/_writevsemantics; - applies one capability decision to immediate and queued output;
- delegates compatible HTTP/2 final writes to
Http2Stream.end(chunk); - adds focused HTTP/1, HTTP/2, net, and stream regression coverage.
39318a1d642 — bounded managed-read reuse
- reuses one unexposed 64 KiB read backing store per
Environment; - retains the existing managed-buffer map as the ownership source;
- preserves exact chunk sizes and independent transferability;
- avoids shared slabs, backing-store amplification, and cross-chunk detach
coupling.
Related work
This PR is intended to supersede the overlapping work while acknowledging the
analysis and implementation effort behind it:
| PR | Reconciliation |
|---|---|
| #64887 | Its corked-output and parser-section work is contained here and extended by the shared vector architecture. |
| #64346 | Its outgoing-overhead objective is covered without retaining isolated micro-hoists or additional per-message cache state. |
| #64393 | Its single-shot objective is covered without introducing a second native response builder or complete-response cache. |
| #64455 | Its lazy-WriteWrap work is integrated, while its read-allocation objective is addressed through bounded internal reuse instead of a JavaScript-visible shared slab. |
The tested #64393 tip returned stale output when a reused Buffer changed from
A to B: main and this branch produced A, B, while that branch produced
A, A. Its cached headline path is therefore not a semantics-preserving
comparison target.
The tested shared slab from #64455 exposed a 64 KiB backing store for small
chunks and coupled their transfer/detach behavior. This branch keeps every
emitted chunk exactly sized and independently transferable.
Performance
Local macOS arm64 Release builds were compared through paired, interleaved
runs against the same f43086d1e4d base.
| Workload | Result |
|---|---|
| All 33 HTTP output configurations | all positive |
| Geometric HTTP gain | +68.11% |
| Geometric gain excluding the previously broken explicit-cork baseline | +29.65% |
| HTTP explicit cork, 16 chunks | 17.6x to 30.2x mean throughput; up to 31.0x median |
| HTTPS explicit cork, 16 chunks | 1,814 → 48,060 req/s (26.5x) |
| HTTP auto-cork, 16 chunks | +47.39% to +57.70% |
| HTTP fixed body, 128 chunks | +154.61% to +168.57% |
| HTTPS auto-cork, 16 chunks | +41.83% |
| HTTPS fixed body, 128 chunks | +88.57% |
| Parser, 4–32 filler headers | +17.71% to +54.14% |
| End-to-end outgoing headers | +1.96% to +10.48% |
| Serial 1 KiB TCP roundtrips | 52,601 → 55,977/s (+6.42%) |
| Saturated read throughput | neutral (+0.08%) |
The exceptional explicit-cork result comes from correcting a path that
previously emitted HTTP framing writes outside the socket-level batch. It is
the removal of a pathological unbatched path, not a claim that every HTTP
workload becomes 30x faster.
The read cache retains exactly 65,536 additional arrayBuffers bytes per
Environment. That value remained constant from 5,000 through 200,000
roundtrips, with no growth in RSS or external memory.
Validation
The output/write reconciliation passed:
- HTTP, HTTPS, and HTTP/2: 831/831
- net, stream, and TLS: 638/638
- child process, cluster, async hooks, and Web Streams: 243/243
- sequential HTTP, net, pipe, and GC tests: 25/25
The final read-buffer binary additionally passed:
- net and TLS: 382/382
- branch-specific changed-path tests: 20/20
- Environment C++ tests: 28/28
- independent TLS transfer/detach verification
- JavaScript and C++ lint
git diff --check
Documentation is unchanged because this is an internal, behavior-preserving
reconciliation.
AI assistance
I developed this PR iteratively with OpenAI Codex as a pair-programming and
analysis tool. It helped trace the affected code paths and related PRs,
explore implementation alternatives, expand test coverage, run and analyze
benchmarks, and edit parts of this description.
I evaluated the alternatives, removed candidates that did not preserve
semantics or demonstrate measurable value, and reviewed and understand the
final diff and reported results.