http: optimize corked writes and header pair tracking

Closed
GE
3mo ago
+384-35

This PR contains two focused HTTP performance improvements without adding or
changing public APIs.

Optimize corked outgoing writes

OutgoingMessage.uncork() previously uncorked the underlying socket before
flushing its buffered HTTP chunk. The individual framing writes therefore
bypassed socket-level batching.

Buffered body data could also be flushed after the terminating chunk when
end() was called while the message was still corked.

This change:

  • flushes buffered HTTP chunks before uncorking the socket;
  • flushes buffered body data before writing the terminating chunk;
  • preserves callback ordering, backpressure, trailers, TLS, and pipelining;
  • prevents a synchronous drain listener from writing after the terminating
    chunk.

Cache maxHeaderPairs

The HTTP parser previously read the JavaScript maxHeaderPairs property for
every header field.

This change caches the value once per independent header section and
invalidates it for:

  • trailers;
  • the next pipelined message;
  • parser reinitialization.

The parser benchmark now explicitly uses the production default of 2000 header
pairs because direct benchmark parsers bypass cleanParser().

Performance

Local macOS arm64 Release results, using the median of three short runs:

ScenarioBeforeAfterImprovement
Core HTTP corked writes17.3k req/s59.5k req/s3.44x
Express corked writes16.6k req/s50.8k req/s3.06x

Parser benchmark improvements:

Header fieldsImprovement
522%
1754%

End-to-end HTTP header benchmarks improved by approximately 4.8% to 7.1%.

Tests

  • Release build completed successfully.
  • ESLint, cpplint, checkimports, and git diff --check passed.
  • The focused HTTP test set passed across 80 repeated executions.
  • All existing test-http-parser-* tests passed.
  • All existing test-http-outgoing-* tests passed.
  • Additional HTTP chunking, trailer, and pipelining tests passed.
  • The new tests cover HTTP and HTTPS, client and server messages, nested
    corking, callback ordering, trailers, backpressure, and queued pipelined
    responses.

Documentation was not changed because no public API or documented behavior is
introduced.