Skip to content

perf_hooks: implement SlidingWindowHistogram - #65825

Draft
jasnell wants to merge 3 commits into
nodejs:mainfrom
jasnell:jasnell/perf-hooks-slidingwindowhistogram
Draft

perf_hooks: implement SlidingWindowHistogram#65825
jasnell wants to merge 3 commits into
nodejs:mainfrom
jasnell:jasnell/perf-hooks-slidingwindowhistogram

Conversation

@jasnell

@jasnell jasnell commented Sep 5, 2026

Copy link
Copy Markdown
Member

Builds on #65806 ... this will remain draft until that lands. The first commit here is from 65806.

Implements SlidingWindowHistogram

const { createSlidingWindowHistogram } = require('node:perf_hooks');

const window = createSlidingWindowHistogram({
  chunks: 6,
  chunkDuration: 10_000,  // chunks are valid for 10 seconds
});

window.record(20_000_000);

// Materialize the current window as an independent Histogram.
const snapshot = window.snapshot();
console.log(snapshot.percentile(99));

Allows for count or time based windows. No timers are used. Validation and allocation are lazy. Uses a ring buffer internally to keep things bounded.

This completes the migration of my typical "performance analysis toolkit" that I've used for some time into built-in primitives.

Example of all this in use: https://github.com/jasnell/fastify-sliding-health

Implements quantile-respectful density estimate calcuation
on Histogram. Helps with tail-focused latency analysis
without retaining raw samples.

Baking this directly into Node.js, based on a 1 million
sample, 1k bin workload, this impl is roughly 150-325x
faster than performing the equivalent in Rscript.

Signed-off-by: James M Snell <[email protected]>
Assisted-by: Opencode
The current recordable `Histogram` does not maintain any sense
of time. Samples accumulate indefinitely as they are collected.
This implements a relatively simple sliding-window mechanism
that can be count or time based. The key benefit is that the
window remains fixed/bounded while samples are recorded.

The sliding window is chunk based. Internally, it maintains
a ring buffer of a fixed number of individual histograms.
When snapshot() is called, those are materialized into a
single combined histogram. As the window slides, older
chunks (and all of the samples they hold) are dropped from
the window so the window drops however many samples happened
to be in that chunk. This does mean that precision of the
window is determined by the chunk size.

Signed-off-by: James M Snell <[email protected]>
Assisted-by: Opencode
@jasnell
jasnell requested a review from mcollina September 5, 2026 16:57
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/performance

@jasnell
jasnell marked this pull request as draft September 5, 2026 16:57
@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 involving general changes in the lib/ or src/ directories. needs-ci PRs that need a full CI run. labels Sep 5, 2026
@codecov

codecov Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.05174% with 124 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.18%. Comparing base (57860ef) to head (f5e52e6).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
src/histogram.cc 83.08% 49 Missing and 64 partials ⚠️
lib/internal/histogram.js 95.45% 7 Missing and 2 partials ⚠️
src/histogram.h 71.42% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65825      +/-   ##
==========================================
+ Coverage   90.14%   90.18%   +0.03%     
==========================================
  Files         769      770       +1     
  Lines      262968   265263    +2295     
  Branches    50052    50407     +355     
==========================================
+ Hits       237049   239218    +2169     
- Misses      16924    17007      +83     
- Partials     8995     9038      +43     
Files with missing lines Coverage Δ
lib/perf_hooks.js 100.00% <100.00%> (ø)
src/histogram-inl.h 94.93% <100.00%> (+10.47%) ⬆️
src/node_perf.cc 86.77% <100.00%> (+0.11%) ⬆️
src/histogram.h 72.54% <71.42%> (-0.18%) ⬇️
lib/internal/histogram.js 96.33% <95.45%> (+0.11%) ⬆️
src/histogram.cc 84.20% <83.08%> (-0.64%) ⬇️

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

@jasnell jasnell added the semver-minor PRs that contain new features and should be released in the next minor version. label Sep 5, 2026
Signed-off-by: James M Snell <[email protected]>
Assisted-by: Opencode
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 involving general changes in the lib/ or src/ directories. needs-ci PRs that need a full CI run. semver-minor PRs that contain new features and should be released in the next minor version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants