Problem
The gateway leaks ~1GB/min of native memory due to structuredClone usage in the session store cache. RSS grows to 4-5GB in minutes while V8 heap stays at ~1.2GB. The gap is native memory from structuredClone's serialization buffer that V8 GC cannot reclaim.
Evidence
- Heap sampling profile: 242MB allocated by
structuredClone in 5 seconds
- RSS 5GB vs V8 heap 1.2GB = 3.8GB native memory leak
- Crash trace: OOM at 4GB during
after_compaction with 8467 facts in hybrid-memory store
- Leak rate: ~1GB/min initially, gateway OOMs within 3-5 minutes
Root Cause
structuredClone in Node.js uses the structured clone algorithm which allocates native (C++) memory for the serialization buffer. For large session stores with frequent compaction cycles, these allocations accumulate faster than the GC can reclaim them.
Hot paths:
src/config/sessions/store-cache.ts:60 — return structuredClone(cached.store) on every cache read
src/config/sessions/store-cache.ts:71 — store: structuredClone(params.store) on every cache write
src/config/sessions/store.ts:269 — return structuredClone(store) in loadSessionStore
src/agents/auth-profiles/store.ts:28 — return structuredClone(store) in cloneAuthProfileStore
Suggested Fix
Replace structuredClone with JSON.parse(JSON.stringify()) or leverage the already-available serializedFromDisk / cached.serialized strings. Session stores are pure JSON data (no Maps, Sets, Dates, or circular refs), so JSON cloning is semantically equivalent but keeps all memory within V8's managed heap.
Environment
- OpenClaw v2026.3.11
- Node.js v25.6.0
- 8467 facts in hybrid-memory SQLite store
- Compaction runs every ~5 minutes
Problem
The gateway leaks ~1GB/min of native memory due to
structuredCloneusage in the session store cache. RSS grows to 4-5GB in minutes while V8 heap stays at ~1.2GB. The gap is native memory from structuredClone's serialization buffer that V8 GC cannot reclaim.Evidence
structuredClonein 5 secondsafter_compactionwith 8467 facts in hybrid-memory storeRoot Cause
structuredClonein Node.js uses the structured clone algorithm which allocates native (C++) memory for the serialization buffer. For large session stores with frequent compaction cycles, these allocations accumulate faster than the GC can reclaim them.Hot paths:
src/config/sessions/store-cache.ts:60—return structuredClone(cached.store)on every cache readsrc/config/sessions/store-cache.ts:71—store: structuredClone(params.store)on every cache writesrc/config/sessions/store.ts:269—return structuredClone(store)inloadSessionStoresrc/agents/auth-profiles/store.ts:28—return structuredClone(store)incloneAuthProfileStoreSuggested Fix
Replace
structuredClonewithJSON.parse(JSON.stringify())or leverage the already-availableserializedFromDisk/cached.serializedstrings. Session stores are pure JSON data (no Maps, Sets, Dates, or circular refs), so JSON cloning is semantically equivalent but keeps all memory within V8's managed heap.Environment