Node.js V8 engine defaults to using roughly half of available system RAM for its heap. On a server with 8 GB, this means a 4 GB heap limit — perfectly reasonable. On the Moto E2 with 1 GB total (and ~400 MB available after Android), V8 would try to allocate ~500 MB and get immediately OOM-killed by the Android Low Memory Killer.
OpenClaw's gateway needs at minimum ~218 MB of heap for its startup dependencies. The first version of this hack set --max-old-space-size=384 as a safe starting point. Later hacks (#16 heap binary search, #20 v8 minimum) refined this down to the absolute minimum of 112 MB through systematic testing.
Before launching the gateway, heavy Google services need to be killed to free enough RAM. But killing Google Mobile Services (GMS) breaks WiFi — a lesson learned the hard way (Hack #24).
Set the V8 heap limit via NODE_OPTIONS:
# Set heap limit — start conservative, then refine
export NODE_OPTIONS='--max-old-space-size=384'
# Kill heavy services to free RAM (but NEVER GMS!)
am force-stop com.android.chrome
am force-stop com.android.vending
am force-stop com.google.android.apps.docs
am force-stop com.google.android.apps.photos
# Launch gateway
npx openclaw gateway run --port 9000The heap limit was progressively reduced through binary search testing:
# Evolution of the heap limit:
# v1: --max-old-space-size=384 (initial safe value)
# v2: --max-old-space-size=256 (after debloat)
# v3: --max-old-space-size=192 (after lazy loading)
# v4: --max-old-space-size=150 (after proot removal)
# v5: --max-old-space-size=128 (tight but works)
# v6: --max-old-space-size=112 (absolute minimum, live heap peaks at 93 MB)
# FAIL: --max-old-space-size=96 (OOM at startup — live heap peaks at 93 MB)# Check current heap limit:
node -e "console.log(v8.getHeapStatistics().heap_size_limit / 1024 / 1024 + ' MB')"
# Expected: 384 MB (or whatever you set)
# Monitor heap usage during gateway startup:
node --max-old-space-size=384 -e "
const v8 = require('v8');
setInterval(() => {
const h = v8.getHeapStatistics();
console.log('Used:', (h.used_heap_size/1024/1024).toFixed(1), 'MB',
'Total:', (h.total_heap_size/1024/1024).toFixed(1), 'MB');
}, 1000);
"com.google.android.gms (Google Mobile Services) — it manages WiFi on many Android devices. Killing it drops the WiFi connection entirely (Hack #24)FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed--max-old-space-size must be set before Node.js starts (via NODE_OPTIONS or command-line flag), not at runtime| Metric | Before | After |
|---|---|---|
| V8 heap limit | ~500 MB (auto) | 384 MB (explicit) |
| OOM kills | Frequent | Rare |
| Gateway stability | Crashes in <1 min | Stable for hours |