Skip to content

stream: add fast paths for webstreams read and pipeTo#61807

Open
mcollina wants to merge 1 commit intonodejs:mainfrom
mcollina:webstreams-fast-paths
Open

stream: add fast paths for webstreams read and pipeTo#61807
mcollina wants to merge 1 commit intonodejs:mainfrom
mcollina:webstreams-fast-paths

Conversation

@mcollina
Copy link
Member

@mcollina mcollina commented Feb 13, 2026

Add internal fast paths to improve webstreams performance without changing the public API or breaking spec compliance.

  1. ReadableStreamDefaultReader.read() fast path: When data is already buffered in the controller's queue, return PromiseResolve() directly without creating a DefaultReadRequest object. This is spec-compliant because read() returns a Promise, and resolved promises still run callbacks in the microtask queue.

  2. pipeTo() batch read fast path: When data is buffered, batch reads directly from the controller queue up to highWaterMark without creating PipeToReadableStreamReadRequest objects per chunk. Respects backpressure by checking desiredSize after each write.

Benchmark results:

  • pipeTo: ~11% faster (***)
  • buffered read(): ~17-20% faster (***)

This was done in partnership with Vercel to improve the performance of React and Next.js, and from a conversation on X with @cramforce.

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/performance
  • @nodejs/web-standards

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. web streams labels Feb 13, 2026
@codecov
Copy link

codecov bot commented Feb 13, 2026

Codecov Report

❌ Patch coverage is 97.59036% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.76%. Comparing base (ae2ffce) to head (5e0474e).
⚠️ Report is 70 commits behind head on main.

Files with missing lines Patch % Lines
lib/internal/webstreams/readablestream.js 97.59% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #61807      +/-   ##
==========================================
+ Coverage   89.75%   89.76%   +0.01%     
==========================================
  Files         674      675       +1     
  Lines      204416   204818     +402     
  Branches    39285    39359      +74     
==========================================
+ Hits       183472   183859     +387     
- Misses      13227    13233       +6     
- Partials     7717     7726       +9     
Files with missing lines Coverage Δ
lib/internal/webstreams/readablestream.js 98.42% <97.59%> (-0.03%) ⬇️

... and 64 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.

@mcollina mcollina added the request-ci Add this label to start a Jenkins CI on a PR. label Feb 13, 2026
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Feb 13, 2026
@mcollina mcollina force-pushed the webstreams-fast-paths branch from 1ad0edd to 080e458 Compare February 13, 2026 20:36
@nodejs-github-bot
Copy link
Collaborator

Add internal fast paths to improve webstreams performance without
changing the public API or breaking spec compliance.

1. ReadableStreamDefaultReader.read() fast path:
   When data is already buffered in the controller's queue, return
   PromiseResolve() directly without creating a DefaultReadRequest
   object. This is spec-compliant because read() returns a Promise,
   and resolved promises still run callbacks in the microtask queue.

2. pipeTo() batch read fast path:
   When data is buffered, batch reads directly from the controller
   queue up to highWaterMark without creating
   PipeToReadableStreamReadRequest objects per chunk. Respects
   backpressure by checking desiredSize after each write.

Benchmark results:
  - pipeTo:          ~11% faster (***)
  - buffered read(): ~17-20% faster (***)

Co-Authored-By: Malte Ubl <malte@vercel.com>
@mcollina mcollina force-pushed the webstreams-fast-paths branch from 080e458 to 5e0474e Compare February 13, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. web streams

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants