{"id":"6a26dd74ddc38a01aa37205a","title":"2026 06 08 Issue 257","path":"how-to/committee/release-notes/2026-06-08-issue-257","contentMarkdown":"# 08-Jun-2026 — memory & heap diagnostics, per-VM heap sizing, plus websocket send reliability [ref #257](https://github.com/nbarrett/ngx-ramblers/issues/257)\n\n## [build 671](https://github.com/nbarrett/ngx-ramblers/actions/runs/27146990563) — [commit adc08f7](https://github.com/nbarrett/ngx-ramblers/commit/adc08f7a8a0be2f58fd0f56bee15d43606eddda4)\n\n_____\n\nTooling to investigate per-site memory and get area sites onto 512MB,\nplus a websocket reliability fix found during testing.\n\nMemory diagnostics (ref #257):\n- GET /api/health/memory (public, numbers only): process.memoryUsage() and\nv8.getHeapStatistics() in MB - rss, heapUsed, external, arrayBuffers, heap\nsize limit. Tells us at a glance whether a site is heap-bound (objects/caches)\nor external-bound (buffers) without a full snapshot.\n- GET /api/health/memory/heap-snapshot (authenticated): streams a V8 heap\nsnapshot straight to S3 (diagnostics/heap-snapshots/<env>-<timestamp>) without\nbuffering it in process memory, returns the key for offline analysis.\n- Diagnostics tab under Admin > System Settings: Refresh reads the memory\nendpoint and shows RSS, heap used/total, heap size limit, external buffers,\nArrayBuffers, uptime and Node version; Capture heap snapshot calls the\nauthenticated endpoint and reports the S3 object key.\n\nWebSocket send reliability:\n- sendMessage called WebSocket.send() while the socket was still CONNECTING\n(connect() resolves immediately when reusing an in-progress connection),\nthrowing \"InvalidStateError: Still in CONNECTING state\" - seen on the backup\nhistory page. Messages sent before the connection opens are now queued and\nflushed in onopen, protecting every consumer (backup, environment\nsetup/create, migration, walks-manager sync, image resize, legacy-redirect\nscrape).\n\nHeap sizing:\n\n- Remove the fixed --max_old_space_size cap from the server start\ncommand. It dated from the Heroku era, where Node read the host\nmachine's RAM rather than the dyno quota and had to be capped by hand.\nOn Fly each machine is a VM whose real RAM Node reads directly, so Node\nnow sizes the old-space heap from the machine it runs on: a 1GB site\ngets more headroom than a 512MB site without every environment sharing\none hardcoded ceiling. worker-server keeps its explicit cap so its\nbrowser and Serenity subprocesses retain room outside the Node heap.","contentHtml":"<h1>08-Jun-2026 — memory &amp; heap diagnostics, per-VM heap sizing, plus websocket send reliability <a href=\"https://github.com/nbarrett/ngx-ramblers/issues/257\">ref #257</a></h1>\n<h2><a href=\"https://github.com/nbarrett/ngx-ramblers/actions/runs/27146990563\">build 671</a> — <a href=\"https://github.com/nbarrett/ngx-ramblers/commit/adc08f7a8a0be2f58fd0f56bee15d43606eddda4\">commit adc08f7</a></h2>\n<hr>\n<p>Tooling to investigate per-site memory and get area sites onto 512MB,\nplus a websocket reliability fix found during testing.</p>\n<p>Memory diagnostics (ref #257):</p>\n<ul>\n<li>GET /api/health/memory (public, numbers only): process.memoryUsage() and\nv8.getHeapStatistics() in MB - rss, heapUsed, external, arrayBuffers, heap\nsize limit. Tells us at a glance whether a site is heap-bound (objects/caches)\nor external-bound (buffers) without a full snapshot.</li>\n<li>GET /api/health/memory/heap-snapshot (authenticated): streams a V8 heap\nsnapshot straight to S3 (diagnostics/heap-snapshots/<env>-<timestamp>) without\nbuffering it in process memory, returns the key for offline analysis.</li>\n<li>Diagnostics tab under Admin &gt; System Settings: Refresh reads the memory\nendpoint and shows RSS, heap used/total, heap size limit, external buffers,\nArrayBuffers, uptime and Node version; Capture heap snapshot calls the\nauthenticated endpoint and reports the S3 object key.</li>\n</ul>\n<p>WebSocket send reliability:</p>\n<ul>\n<li>sendMessage called WebSocket.send() while the socket was still CONNECTING\n(connect() resolves immediately when reusing an in-progress connection),\nthrowing &quot;InvalidStateError: Still in CONNECTING state&quot; - seen on the backup\nhistory page. Messages sent before the connection opens are now queued and\nflushed in onopen, protecting every consumer (backup, environment\nsetup/create, migration, walks-manager sync, image resize, legacy-redirect\nscrape).</li>\n</ul>\n<p>Heap sizing:</p>\n<ul>\n<li>Remove the fixed --max_old_space_size cap from the server start\ncommand. It dated from the Heroku era, where Node read the host\nmachine&#39;s RAM rather than the dyno quota and had to be capped by hand.\nOn Fly each machine is a VM whose real RAM Node reads directly, so Node\nnow sizes the old-space heap from the machine it runs on: a 1GB site\ngets more headroom than a 512MB site without every environment sharing\none hardcoded ceiling. worker-server keeps its explicit cap so its\nbrowser and Serenity subprocesses retain room outside the Node heap.</li>\n</ul>\n"}