Skip to content

feat(node): implement performance.nodeTiming and uvMetricsInfo#32861

Draft
bartlomieju wants to merge 1 commit intomainfrom
feat/node-timing-uv-metrics
Draft

feat(node): implement performance.nodeTiming and uvMetricsInfo#32861
bartlomieju wants to merge 1 commit intomainfrom
feat/node-timing-uv-metrics

Conversation

@bartlomieju
Copy link
Member

Summary

Closes #31085

Implements performance.nodeTiming from node:perf_hooks with a proper PerformanceNodeTiming class instead of the empty object stub ({}).

Before

import { performance } from 'node:perf_hooks';
setImmediate(() => console.log(performance.nodeTiming.uvMetricsInfo));
// undefined

After

import { performance } from 'node:perf_hooks';
setImmediate(() => console.log(performance.nodeTiming.uvMetricsInfo));
// { loopCount: 1, events: 0, eventsWaiting: 0 }

Changes

deno_core (libs/core/uv_compat.rs, libs/core/runtime/jsruntime.rs):

  • Add loop_count, events, events_waiting counters to UvLoopInner
  • loop_count increments each event loop iteration
  • events increments per TCP/TTY I/O event processed
  • Expose via uv_loop_metrics_info() public function

ext/node (ops/perf_hooks.rs, lib.rs):

  • Add op_node_uv_metrics_info op that reads counters from UvLoop in OpState

ext/node (polyfills/perf_hooks.js):

  • Replace performance.nodeTiming = {} with PerformanceNodeTiming class
  • Properties: name, entryType, startTime, duration, timing milestones, loopStart, loopExit, idleTime, uvMetricsInfo, toJSON()
  • uvMetricsInfo getter returns real { loopCount, events, eventsWaiting }

Still stubbed/approximated

  • Timing milestones (nodeStart, v8Start, environment, bootstrapComplete) are approximated
  • idleTime returns 0 (needs idle time tracking in UvLoopInner)
  • loopExit returns -1 (needs process exit hook)
  • events_waiting counter is not yet incremented

Test plan

  • Manual: performance.nodeTiming.uvMetricsInfo returns object with correct shape
  • Manual: loopCount increments after event loop iterations
  • cargo check passes

🤖 Generated with Claude Code

Implement `performance.nodeTiming` from `node:perf_hooks` with a
proper `PerformanceNodeTiming` class instead of an empty object stub.

Implements:
- `name`, `entryType`, `startTime`, `duration` (PerformanceEntry props)
- `nodeStart`, `v8Start`, `environment`, `bootstrapComplete` (timing
  milestones, approximated since Deno doesn't track these separately)
- `loopStart`, `loopExit`, `idleTime` (event loop timing, partially
  stubbed)
- `uvMetricsInfo` getter returning `{ loopCount, events, eventsWaiting }`
  backed by actual event loop counters in deno_core's UvLoopInner
- `toJSON()` for serialization

The event loop metrics are tracked in deno_core:
- `loop_count`: incremented each event loop iteration
- `events`: incremented per I/O event (TCP/TTY) processed
- `events_waiting`: reserved for future use
- Exposed via `uv_loop_metrics_info()` and `op_node_uv_metrics_info`

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bartlomieju bartlomieju added the ci-draft Run the CI on draft PRs. label Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-draft Run the CI on draft PRs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

performance.nodeTiming.uvMetricsInfo from node:perf_hooks behaves differently in Deno compared to Node.js

1 participant