Skip to content

http: fast-forward teardown of unread messages - #65732

Open
mcollina wants to merge 1 commit into
nodejs:mainfrom
mcollina:http-fast-request-teardown
Open

http: fast-forward teardown of unread messages#65732
mcollina wants to merge 1 commit into
nodejs:mainfrom
mcollina:http-fast-request-teardown

Conversation

@mcollina

@mcollina mcollina commented Sep 2, 2026

Copy link
Copy Markdown
Member

When a response finishes and the incoming message was fully received but never read (every body-less request that the handler ignores), _dump() currently calls resume(), which schedules a resume_ tick, emits 'resume' to no listeners, and runs the flow() machinery just to reach EOF.

With this change _dump() calls read(0) instead when the message is already ended, undestroyed and fully drained: read(0) at EOF goes straight to endReadable() (idempotent since #65310), so the 'end'/'close' sequence is unchanged and still asynchronous. Incomplete messages (body still arriving when the response ends) keep the resume() path. Unread client responses dumped by _http_client benefit the same way.

For a hello-world HTTP server this removes one nextTick (7 → 6 per request) and one dead emit (9 → 8 per request).

Benchmark (i7-7700, server pinned to one core, wrk -t2 -c50 on separate physical cores, 8 interleaved rounds; CPU measured from /proc/<pid>/stat over the run):

CPU µs/request user µs/request
main 26.6 16.7
this PR 25.3 (−4.2%) 15.8 (−5%)

The patched binary won all 8 rounds and served ~4% more requests per round.

test/parallel/test-http-*, test-stream-*, test-net-* and test-https-* all pass; test-http-dump-req-when-res-ends covers the mid-body dump case, which keeps the previous behavior.

——

This was generated with the assistance of AI. I reviewed all the code.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/http
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added http Issues and PRs related to the http subsystem. needs-ci PRs that need a full CI run. labels Sep 2, 2026
When a response finishes and the incoming message was fully received
but never read, _dump() no longer goes through resume(): read(0) at
EOF schedules the 'end' emission directly, skipping the resume_ tick,
the 'resume' emit and the flow() machinery.

Reduces the per-request nextTick count of a hello-world HTTP server
from 7 to 6 and CPU per request by ~4%.

Signed-off-by: Matteo Collina <hello@matteocollina.com>
@mcollina
mcollina force-pushed the http-fast-request-teardown branch from e4f8389 to 803bd87 Compare September 2, 2026 07:04
@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.04%. Comparing base (7b0de5e) to head (803bd87).
⚠️ Report is 56 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65732      +/-   ##
==========================================
- Coverage   90.05%   90.04%   -0.01%     
==========================================
  Files         754      754              
  Lines      255722   256525     +803     
  Branches    48314    48530     +216     
==========================================
+ Hits       230281   230996     +715     
- Misses      16555    16645      +90     
+ Partials     8886     8884       -2     
Files with missing lines Coverage Δ
lib/_http_incoming.js 97.96% <100.00%> (+0.02%) ⬆️

... and 70 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

http Issues and PRs related to the http subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants