Skip to content

Conversation

@floating-dynamo
Copy link
Contributor

@floating-dynamo floating-dynamo commented Dec 12, 2025

Description

  • Current Architecture: It seems the SDK creates ONE Global Isolate (a single Virtual Machine) when the server starts, and reuses it for every single request (2000+ requests).
  • The Leak: The V8 engine inside that single Isolate is accumulating "Script Compilation" data, fragmentation, or hidden caches from running 2000 different closures. Eventually, the Isolate's heap limit (usually 128MB) explodes, or it leaks into the main process.

The Strategy:

  1. Create a fresh Isolate for every single request.
  2. Run the code.
  3. Dispose (Destroy) the Isolate immediately.

This guarantees memory cleanup because the entire memory block is freed by C++.

Testing
Notion doc for dev testing - https://www.notion.so/builderio/ENG-10865-testing-memory-leak-fix-2cb3d7274be5804988edd838631a6b62

Screenshot


Note

Switches Node runtime to create a fresh isolated-vm per request and dispose it after execution, addressing memory leaks; updates changeset to bump minor versions across SDKs.

  • Node runtime (packages/sdks/.../node-runtime.ts):
    • Create a new ivm.Isolate per request using stored IsolateOptions and dispose it in finally.
    • Remove global Context/shared isolate; eliminate setIsolateContext/getIsolateContext.
    • Update setIvm to accept optional options and store them for per-request use.
  • Release:
    • Changeset adds minor version bumps for multiple @builder.io/* SDKs and notes memory leak elimination.

Written by Cursor Bugbot for commit e327221. This will update automatically on new commits. Configure here.

…memory leaks

- Removed global IVM_CONTEXT and related functions to ensure isolates are created anew for each request.
- Updated `setIvm` to utilize options per request instead of globally.
- Enhanced `runInNode` to initialize the isolate and context directly within the function, improving memory management and cleanup.
- Added comments to clarify changes and rationale for the new approach.

This refactor aims to enhance performance and reliability by eliminating potential memory leaks associated with persistent isolates.
…roved memory management

- Added `IVM_OPTIONS` to store isolate options, defaulting to a memory limit of 128.
- Updated `setIvm` to accept and store options for each request, enhancing flexibility.
- Modified `runInNode` to utilize stored options when creating isolates, ensuring consistent memory management.
- Improved comments for clarity on the new approach and its benefits.

This refactor aims to further optimize memory usage and isolate management in the node runtime.
@changeset-bot
Copy link

changeset-bot bot commented Dec 12, 2025

🦋 Changeset detected

Latest commit: e327221

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 10 packages
Name Type
@builder.io/sdk Minor
@builder.io/react Minor
@builder.io/sdk-angular Minor
@builder.io/sdk-react-nextjs Minor
@builder.io/sdk-qwik Minor
@builder.io/sdk-react Minor
@builder.io/sdk-react-native Minor
@builder.io/sdk-solid Minor
@builder.io/sdk-svelte Minor
@builder.io/sdk-vue Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@nx-cloud
Copy link

nx-cloud bot commented Dec 12, 2025

View your CI Pipeline Execution ↗ for commit e327221

Command Status Duration Result
nx test @snippet/react ✅ Succeeded 2m 1s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-17 11:28:37 UTC

- Eliminated the unused `Context` import from `isolated-vm` in the node-runtime file.
- This change simplifies the code and improves readability by removing unnecessary dependencies.

This refactor contributes to maintaining a clean and efficient codebase.
@floating-dynamo floating-dynamo self-assigned this Dec 12, 2025
@floating-dynamo floating-dynamo changed the title fix[testVueSdk]: try to not use global isolate and create fresh instance for each request fix[testVueSdk]: try to not use a global isolate instance and create fresh instance for each request Dec 12, 2025
Copy link
Contributor

@sanyamkamat sanyamkamat left a comment

Choose a reason for hiding this comment

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

  • add changeset. Recommendation for Major upgrade as we are changing how we handle JVM garbage collection here.

Copy link
Contributor

@samijaber samijaber left a comment

Choose a reason for hiding this comment

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

I agree with this PR: we should find a way to dispose of the IVM isolate at the end of a request to avoid memory leaks.

However, this PR goes to the other extreme and creates a new Isolate for every individual data binding. If the content item has 1,000 dynamic data bindings, it should be more performant to reuse the isolate instance for all of its data bindings.

I would suggest the following:

  • double check the impact of this PR on pages with very large amounts of data bindings (1000s)
  • if my assumption is correct, and the test shows a noticeable degradation in performance, then we should find a way to reuse the IVM isolate for all bindings within the same <Content> render.

samijaber added a commit that referenced this pull request Dec 15, 2025
@floating-dynamo floating-dynamo changed the title fix[testVueSdk]: try to not use a global isolate instance and create fresh instance for each request fix[gen2Sdks]: try to not use a global isolate instance and create fresh instance for each request Dec 17, 2025
@floating-dynamo floating-dynamo changed the title fix[gen2Sdks]: try to not use a global isolate instance and create fresh instance for each request fix[gen2]: try to not use a global isolate instance and create fresh instance for each request Dec 17, 2025
@floating-dynamo floating-dynamo merged commit 659cc99 into main Dec 17, 2025
93 of 94 checks passed
@floating-dynamo floating-dynamo deleted the vue-sdk-issue-fix-2 branch December 17, 2025 11:30
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.

4 participants