microsoft / microsoft/onnxruntime
[Bug] [Node.js] First InferenceSession creation allocates 15-43GB on macOS ARM64 — no session cycling
@fs-eire is already working on this.
Since Mar 19, 2026.
- Dominant language
- C++
- Stars
- 21.9k
- Forks
- 4.2k
- Avg merge
- 4d 11h
- Merged PRs (30d)
- 184
Description
### Describe the bug
Creating a **single** `InferenceSession` for a ~500MB fp32 ONNX embedding model (`nomic-ai/nomic-embed-text-v1.5`) causes the Node.js process to allocate 15-43GB of RSS memory on macOS ARM64. This is not a session create/release cycle leak (as described in #25325) — this happens on the **first and only** session creation, before any inference runs.
The allocation spike is instantaneous — RSS goes from ~2.4GB to 15GB in under 2 seconds (observed via polling `ps -o rss`). On `onnxruntime-node@1.22.0`, it reached 43GB and Jetsam-killed the process on a 36GB machine.
### Urgency
This is a showstopper for any Node.js application that loads ONNX models on macOS ARM64. We tested three versions — all broken with different symptoms. We've had to remove ONNX from our default pipeline entirely.
### To reproduce
```javascript
// Minimal reproduction — single session, no cycling
import { pipeline } from "@huggingface/transformers";
// This single call triggers the 15GB+ allocation
const embedder = await pipeline("feature-extraction", "nomic-ai/nomic-embed-text-v1.5", {
dtype: "fp32",
device: "cpu"
});
// Process RSS is already 15GB+ before this line executes
const result = await embedder("hello world", { pooling: "mean", normalize: true });
```
Running in a Node.js Worker Thread (via `worker_threads`) makes it worse but the bug reproduces on the main thread too.
### Environment
- **OS:** macOS 15.7.3 (Sequoia) — `Darwin Kernel Version 24.6.0`
- **Hardware:** MacBook Pro M3 Pro, 36GB RAM
- **Node.js:** 22.22.0
- **Architecture:** ARM64 (Apple Silicon)
### Versions tested
| onnxruntime-node | @huggingface/transformers | Result |
|-----------------|--------------------------|--------|
| **1.21.0** | 3.8.1 | `FATAL ERROR: HandleScope::HandleScope Entering the V8 API without proper locking in place` — process crashes immediately in Worker Thread |
| **1.22.0** | 3.8.1 | 43GB RSS allocation on first session create. Jetsam kills the process. On a second attempt, hard-froze the MacBook requiring force reboot (no panic log, no Jetsam report — pure deadlock). |
| **1.24.3** | 3.8.1 | 15GB RSS allocation on first session create. Jetsam kills the process within seconds. |
All versions installed via npm `overrides` to force the transitive dependency from `@huggingface/transformers`:
```json
{ "overrides": { "onnxruntime-node": "1.24.3" } }
```
### Memory watchdog data (v1.24.3)
We ran our indexing tool with a 2-second RSS polling watchdog:
```
[2] RSS: 2375 MB ← model file loaded into memory, session not yet created
[3] RSS: 2376 MB
[4] RSS: 2433 MB
[5] RSS: 15064 MB ← session creation completed — 12.6GB spike in <2 seconds
KILLING — exceeded 4GB watchdog threshold
```
### Jetsam report data (v1.22.0 — earlier test without watchdog)
From `/Library/Logs/DiagnosticReports/JetsamEvent-2026-03-19-091753.ips`:
```
"largestProcess": "node"
"free": 4507 pages (73MB)
Top processes at kill time:
node: 43314 MB (2,772,107 pages × 16KB)
com.apple.Virtualization.Virtual: 8105 MB
WindowServer: 1314 MB
```
The `node` process consumed **43.3GB** on a **36GB machine** — clearly allocating virtual memory far beyond physical RAM.
### Relationship to #25325
Issue #25325 describes memory leaks during **session create/release cycling**. Our bug is different:
- **Single session creation** — no release, no cycling
- **Instantaneous allocation** — not a gradual leak
- **First load** — happens before any inference call
- **Scale is wrong** — a 500MB model should not allocate 15-43GB
This may share root cause with #25325 (allocator retention, arena pre-allocation) but the trigger is different. The community workaround for #25325 (spawn short-lived child processes) doesn't help here because the leak happens on the first and only session.
### What we've tried
- `CpuMemArena: false` — not directly configurable through `@huggingface/transformers` pipeline API
- Different `dtype` values — fp32 tested, q8 was not tested before we abandoned ONNX
- Worker Thread vs Main Thread — both leak, Worker Thread is worse
- Three different `onnxruntime-node` versions — all broken
### Expected behavior
Loading a 500MB ONNX model should use approximately 500MB-1GB of RSS, not 15-43GB.
### Impact
We maintain a local code search MCP server for AI coding assistants. We had to:
1. Remove ONNX from the default pipeline
2. Make our GitHub repository private (the published code crashes machines)
3. Abandon 10 sprints of work built on `@huggingface/transformers` ONNX backend
4. Plan a full replacement with `node-llama-cpp` (GGUF models) as the default embedding backend
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.