Skip to content

perf(node): port internal bindings to Rust#35182

Open
nathanwhit wants to merge 33 commits into
denoland:mainfrom
nathanwhit:codex/node-internal-bindings-rust
Open

perf(node): port internal bindings to Rust#35182
nathanwhit wants to merge 33 commits into
denoland:mainfrom
nathanwhit:codex/node-internal-bindings-rust

Conversation

@nathanwhit

Copy link
Copy Markdown
Member

Summary

Ports a large set of ext:deno_node/internal_binding/* modules from JS/TS into Rust-backed bindings, reducing snapshot payload and moving binding construction into native code.

This includes Rust ports for node internal binding utilities, constants, buffer/util, file/options, async/handle/stream/tcp/pipe/http2/tls/http parser, UDP, DNS, and related helpers. It also keeps startup/runtime overhead in check by caching HTTP parser callback trampolines and avoiding unused stream request allocations.

Motivation

The existing JS internal binding modules are serialized into the startup snapshot. Moving them to Rust shrinks the JS snapshot surface and makes the native binding layer more explicit.

Performance Notes

Compared against main@upstream d01f3783 using release-lite binaries:

  • Snapshot profile total: 2,710,344 -> 2,674,672 bytes, net -35,672 bytes
  • Combined node:http client+server keep-alive benchmark, 20k requests:
    • main: 977.1 ms
    • stack: 1.018 s
    • delta: +4.2%
  • TCP echo 200k:
    • main: 152.7 ms
    • stack: 160.0 ms
    • delta: +4.8%
  • Combined node:http client+server RSS, 10 runs:
    • peak RSS: 230.9 MiB -> 105.4 MiB
    • peak-idle RSS: 230.9 MiB -> 105.4 MiB
    • initial idle RSS stayed flat at about 55 MiB

The HTTP benchmark is intentionally combined client+server in one Deno process over a loopback keep-alive socket, so it exercises both request and response parser paths.

Validation

  • cargo build --profile release-lite -p deno --bin deno
  • cargo build --bin deno --bin test_server
  • ./x test-node http_parser
  • Focused tests/unit_node/http_test.ts filters:
    • AsyncLocalStorage propagates into request handler
    • AsyncLocalStorage enterWith in request handler is isolated
    • async_hooks observes request execution resource
    • rawHeaders are in flattened format

Profiling was done with flamey and --v8-flags=--perf-basic-prof.

@nathanwhit nathanwhit marked this pull request as ready for review June 12, 2026 21:55
@nathanwhit nathanwhit force-pushed the codex/node-internal-bindings-rust branch from cbc895b to bbb55e3 Compare June 12, 2026 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant