GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — perf: reduce EventSourceStream parser allocations by trivikr · Pull Request #5032 · nodejs/undici

Conversation

@trivikr

@trivikr trivikr commented Apr 15, 2026

Copy link
Copy Markdown
Member

This relates to...

Fixes: #2630

Rationale

EventSourceStream was doing avoidable work on long-lived SSE streams by concatenating the buffered input for every chunk, allocating strings for every parsed field name, and replacing the internal event object after each dispatch. That creates unnecessary allocation churn in the hot path, especially when servers deliver heavily fragmented chunks.

Changes

  • Replaced the single-buffer Buffer.concat([buffer, chunk]) approach with chunk-list buffering plus cursors.
  • Kept line parsing lazy so buffers are only concatenated when a logical line spans multiple chunks.
  • Matched data, event, id, and retry field names from bytes instead of decoding field strings first.
  • Validated retry and id directly from bytes before decoding their values.
  • Reset the parser event state in place instead of allocating a fresh event object on every event boundary.
  • Added focused EventSourceStream benchmarks covering realistic payloads, fragmented chunking, and BOM-prefixed input.

Features

N/A

Bug Fixes

Reduced allocation pressure in the EventSourceStream parser hot path for fragmented SSE streams.

Breaking Changes and Deprecations

  • No public API changes.
  • Internally, processEvent(event) now receives a reused parser event object instead of a freshly allocated object each time.

Status

  • I have read and agreed to the Developer's Certificate of Origin
  • Tested
  • Benchmarked (optional)
  • Documented
  • Review ready
  • In review
  • Merge ready

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
trivikr added 2 commits April 14, 2026 23:14
@trivikr
perf: reduce EventSourceStream parser allocations
f1e2b06
Assisted-by: OpenAI:gpt-5.4
Signed-off-by: Kamat, Trivikram <[email protected]>
@trivikr
bench: add EventSourceStream parsing benchmarks
21710c4
@trivikr

trivikr commented Apr 15, 2026

Copy link
Copy Markdown
Member Author

Benchmarks

Before

$ node benchmarks/eventsource/eventsource-stream.mjs
clk: ~3.18 GHz
cpu: Apple M1 Pro
runtime: node 24.14.0 (arm64-darwin)

benchmark                   avg (min … max) p75 / p99    (min … top 1%)
------------------------------------------- -------------------------------
• EventSourceStream parsing (250 events)
------------------------------------------- -------------------------------
single chunk                 523.13 µs/iter 517.21 µs █                    
                    (493.29 µs … 853.88 µs) 731.96 µs █                    
                    (167.25 kb …   1.18 mb) 659.19 kb █▆▂▁▁▂▃▃▂▂▁▁▁▁▁▁▁▁▁▁▁

256-byte chunks              544.53 µs/iter 538.29 µs █                    
                      (519.42 µs … 1.71 ms) 749.08 µs █▆                   
                    (110.61 kb …   2.11 mb) 711.91 kb ██▆▂▂▂▂▂▂▁▁▂▁▂▁▁▁▁▁▁▁

64-byte chunks               597.89 µs/iter 600.50 µs  █                   
                    (580.54 µs … 844.83 µs) 726.08 µs ▆█                   
                    (148.83 kb …   1.41 mb) 868.50 kb ██▇▇▄▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁

8-byte chunks                  1.14 ms/iter   1.14 ms  █ ▃                 
                        (1.11 ms … 1.30 ms)   1.27 ms  █▇█▅                
                    (659.22 kb …   2.29 mb)   2.29 mb ▆████▆▃▂▂▂▂▁▁▁▁▂▂▃▂▁▂

1-byte chunks                  5.49 ms/iter   5.56 ms ▃█▆▇                 
                        (5.20 ms … 6.90 ms)   6.63 ms █████▃▂              
                    ( 13.86 mb …  13.86 mb)  13.86 mb ███████▆▂█▁▁▃▁▂▁▂▁▁▂▂

• EventSourceStream parsing with BOM
------------------------------------------- -------------------------------
BOM + 8-byte chunks            1.16 ms/iter   1.17 ms  █                   
                        (1.13 ms … 1.39 ms)   1.34 ms  █ ▄                 
                    (  2.29 mb …   2.30 mb)   2.29 mb ▆███▅▅▂▂▂▁▁▁▁▁▁▁▁▁▁▂▁

BOM + 1-byte chunks            5.42 ms/iter   5.49 ms  █▂                  
                        (5.32 ms … 5.74 ms)   5.70 ms  ██                  
                    ( 13.86 mb …  13.87 mb)  13.86 mb ▃██▆▂▆▄▂▂██▂▃▅▁▁▂▁▂▂▂

After

$ node benchmarks/eventsource/eventsource-stream.mjs
clk: ~3.14 GHz
cpu: Apple M1 Pro
runtime: node 24.14.0 (arm64-darwin)

benchmark                   avg (min … max) p75 / p99    (min … top 1%)
------------------------------------------- -------------------------------
• EventSourceStream parsing (250 events)
------------------------------------------- -------------------------------
single chunk                 356.42 µs/iter 333.46 µs █▇                   
                      (320.71 µs … 6.80 ms) 661.83 µs ██                   
                    ( 10.12 kb …   1.12 mb) 210.89 kb ██▃▄▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

256-byte chunks              364.56 µs/iter 363.38 µs   █                  
                    (352.96 µs … 517.63 µs) 443.25 µs ███                  
                    ( 62.13 kb …   1.30 mb) 301.20 kb ███▆▂▂▂▂▂▂▂▁▁▁▁▁▁▁▁▁▁

64-byte chunks               465.56 µs/iter 463.33 µs  █▅                  
                    (445.42 µs … 650.08 µs) 588.88 µs ▅██                  
                    ( 14.05 kb …   1.09 mb) 552.85 kb ███▆▄▂▂▂▂▂▂▁▂▁▁▁▁▁▁▁▁

8-byte chunks                  1.01 ms/iter   1.00 ms    █                 
                      (976.13 µs … 1.22 ms)   1.13 ms  ▆▄█                 
                    (  1.08 mb …   2.11 mb)   1.83 mb ▆████▄▃▂▂▂▁▁▁▁▁▁▂▂▂▂▁

1-byte chunks                  5.10 ms/iter   5.10 ms  █                   
                        (4.84 ms … 6.46 ms)   6.43 ms  █ ▃                 
                    ( 11.93 mb …  11.93 mb)  11.93 mb ▄███▄▃▁▁▂▁▁▁▂▁▁▁▂▁▂▁▁

• EventSourceStream parsing with BOM
------------------------------------------- -------------------------------
BOM + 8-byte chunks            1.02 ms/iter   1.02 ms   █                  
                      (993.00 µs … 1.33 ms)   1.19 ms   █                  
                    (  1.84 mb …   1.88 mb)   1.84 mb ▄▃██▃▃▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁

BOM + 1-byte chunks            5.13 ms/iter   5.20 ms     ▆█               
                        (4.96 ms … 5.37 ms)   5.36 ms     ██▄ ▄   ▃        
                    ( 11.93 mb …  11.93 mb)  11.93 mb ▅██▅█████▇█▆█▆▇▇▅▅▅▅▂
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@codecov-commenter

codecov-commenter commented Apr 15, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.16%. Comparing base (2eb9ddc) to head (f660a6e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5032      +/-   ##
==========================================
+ Coverage   93.14%   93.16%   +0.01%     
==========================================
  Files         110      110              
  Lines       36117    36212      +95     
==========================================
+ Hits        33642    33736      +94     
- Misses       2475     2476       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 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.
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@metcoder95
metcoder95 requested a review from Uzlopak April 15, 2026 09:24
@trivikr
Merge branch 'nodejs:main' into eventsource-stream-2
7d3e5de
mcollina
mcollina approved these changes Apr 22, 2026
View reviewed changes

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mcollina
mcollina requested a review from KhafraDev April 22, 2026 08:07
@trivikr
Merge branch 'nodejs:main' into eventsource-stream-2
f660a6e
KhafraDev
KhafraDev approved these changes Apr 30, 2026
View reviewed changes

@KhafraDev KhafraDev left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EventSource isn't really my area of expertise.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@trivikr
trivikr merged commit aeed21a into nodejs:main Apr 30, 2026
35 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@trivikr
trivikr deleted the eventsource-stream-2 branch May 1, 2026 00:29
@github-actions github-actions Bot mentioned this pull request May 1, 2026
[Release] v8.2.0 #5152
Merged
mcollina added a commit that referenced this pull request Aug 4, 2026
@mcollina @trivikr
perf: reduce EventSourceStream parser allocations (#5032) (#5646)
f408f12
Assisted-by: OpenAI:gpt-5.4

(cherry picked from commit aeed21a)

Signed-off-by: Kamat, Trivikram <[email protected]>
Co-authored-by: Trivikram Kamat <[email protected]>
mcollina added a commit that referenced this pull request Aug 4, 2026
@mcollina @trivikr
perf: reduce EventSourceStream parser allocations (#5032) (#5647)
bd90fff
Assisted-by: OpenAI:gpt-5.4

(cherry picked from commit aeed21a)

Signed-off-by: Kamat, Trivikram <[email protected]>
Co-authored-by: Trivikram Kamat <[email protected]>
This was referenced Sep 4, 2026
[Release] v7.29.1 #5772
Merged
[Release] v6.28.1 #5773
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@mcollina mcollina mcollina approved these changes
@KhafraDev KhafraDev KhafraDev approved these changes
@Uzlopak Uzlopak Awaiting requested review from Uzlopak

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Reduce Buffer operations in EventSource

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@trivikr @codecov-commenter @mcollina @KhafraDev
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.