Skip to content

v8: add heap profile API#62273

Open
IlyasShabi wants to merge 3 commits intonodejs:mainfrom
IlyasShabi:ishabi/v8_heap_profile
Open

v8: add heap profile API#62273
IlyasShabi wants to merge 3 commits intonodejs:mainfrom
IlyasShabi:ishabi/v8_heap_profile

Conversation

@IlyasShabi
Copy link
Member

This PR succeeds #60231 by @theanarkh and adds parameter support for heap sampling on both the main thread and workers.

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Mar 16, 2026
@IlyasShabi IlyasShabi force-pushed the ishabi/v8_heap_profile branch from 44720ea to 0221ebd Compare March 16, 2026 09:51
@IlyasShabi IlyasShabi marked this pull request as ready for review March 16, 2026 09:52
@IlyasShabi IlyasShabi force-pushed the ishabi/v8_heap_profile branch from 0221ebd to 5861bc1 Compare March 16, 2026 10:05
@Qard
Copy link
Member

Qard commented Mar 16, 2026

cc @nodejs/diagnostics

doc/api/v8.md Outdated
console.log(profile);
```

## `v8.heapProfilerConstants`
Copy link
Member

Choose a reason for hiding this comment

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

We very rarely expose bitfields and instead generally just let users pass us e.g. arrays of flags or options that we then translate in the JS wrapper. I could see exceptions made for highly performance-sensitive APIs, but I don't think this is an example of that

Copy link
Member Author

Choose a reason for hiding this comment

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

I was looking for a proper way to do this while preserving the same naming as V8.
Fixed

Copy link
Member

@Qard Qard left a comment

Choose a reason for hiding this comment

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

Some DX and future-looking recommendations, but otherwise LGTM.

doc/api/v8.md Outdated
These constants can be combined using bitwise OR to pass as the `flags`
parameter.

## `v8.startHeapProfile([sampleInterval[, stackDepth[, flags]]])`
Copy link
Member

Choose a reason for hiding this comment

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

It might be better to take an object given that there's no particular dependency between any of these parameters--one could want to set any of them independently of the others.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree

added: REPLACEME
-->

* Returns: {string}
Copy link
Member

Choose a reason for hiding this comment

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

Might be better to return a Buffer instead. It'd give us more flexibility to add binary formats in the future. I'd like to add support at some point in the future for the pprof-derived format being defined in OpenTelemetry at the moment, which is a binary format.

Copy link
Member Author

Choose a reason for hiding this comment

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

IIRC worker.stopHeapProfile() already returns a JSON since v22, so changing the return type to Buffer would be a breaking change. For now this PR keeps the main thread consistent with the worker.
We could add a format option { format: 'json' | 'pprof' } in a follow up PR when binary format support is needed. wdyt?

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

❌ Patch coverage is 94.04255% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.77%. Comparing base (4579957) to head (f39064b).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
src/util.cc 85.71% 1 Missing and 8 partials ⚠️
src/node_v8.cc 94.00% 1 Missing and 2 partials ⚠️
lib/v8.js 95.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62273      +/-   ##
==========================================
- Coverage   89.67%   88.77%   -0.91%     
==========================================
  Files         676      677       +1     
  Lines      206555   206737     +182     
  Branches    39554    39482      -72     
==========================================
- Hits       185230   183522    -1708     
- Misses      13461    15279    +1818     
- Partials     7864     7936      +72     
Files with missing lines Coverage Δ
lib/internal/v8/heap_profile.js 100.00% <100.00%> (ø)
lib/internal/worker.js 96.61% <100.00%> (+0.09%) ⬆️
src/node_worker.cc 82.02% <100.00%> (+0.41%) ⬆️
src/node_worker.h 91.66% <ø> (ø)
src/util.h 91.20% <100.00%> (+0.29%) ⬆️
lib/v8.js 98.21% <95.00%> (-0.83%) ⬇️
src/node_v8.cc 82.82% <94.00%> (+1.11%) ⬆️
src/util.cc 87.22% <85.71%> (-0.23%) ⬇️

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

c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants