fix(dashboard): measure V8 heap against its limit, not its current size

The Health Score's heap component divided heapUsed by heapTotal, which is
only what V8 has grown the heap to so far, so a healthy server read 70-90%
and dragged the score down. GET /api/settings/info now also reports
server.memory.heapLimit (v8 heap_size_limit, the ceiling the process dies
at); the V8 Heap bar and the Health Score divide by it, falling back to
heapTotal against an older server.
This commit is contained in:
2026-09-23 16:46:00 +07:00
parent 94ee2dc79c
commit 764b967856
5 changed files with 35 additions and 8 deletions
+8
View File
@@ -1896,6 +1896,14 @@ describe("Transcript cache integration", () => {
assert.equal(res.body.server.version, pkg.version);
});
it("reports the V8 heap LIMIT, not just the currently allocated heapTotal", async () => {
const res = await fetch("/api/settings/info");
const { heapUsed, heapTotal, heapLimit } = res.body.server.memory;
assert.ok(Number.isFinite(heapLimit), "heapLimit should be a number");
// heapTotal is what V8 has grown to so far; the limit is the ceiling.
assert.ok(heapLimit >= heapTotal && heapLimit > heapUsed);
});
it("should evict cache entry on SessionEnd", async () => {
const tmpTranscript = path.join(os.tmpdir(), `test-evict-${Date.now()}.jsonl`);
fs.writeFileSync(
+1
View File
@@ -139,6 +139,7 @@ const SETTINGS_INFO_EXAMPLE = {
heapTotal: 71303168,
heapUsed: 58392104,
external: 3211884,
heapLimit: 4345298944,
arrayBuffers: 1048576,
},
cpu_load: [2.13, 2.45, 2.31],
+5 -1
View File
@@ -7,6 +7,7 @@ const { Router } = require("express");
const fs = require("fs");
const path = require("path");
const os = require("os");
const v8 = require("v8");
const { db, stmts, DB_PATH, DEFAULT_PRICING, applyIntroPricing } = require("../db");
const { getConnectionCount } = require("../websocket");
const { transcriptCache } = require("./hooks");
@@ -121,7 +122,10 @@ router.get("/info", (req, res) => {
node_version: process.version,
platform: process.platform,
ws_connections: getConnectionCount(),
memory: process.memoryUsage(),
// heapTotal is only what V8 has grown the heap to SO FAR, so used/total
// sits at 70-90% on a perfectly healthy process. heapLimit is the ceiling
// the process actually dies at — the denominator a "heap used %" needs.
memory: { ...process.memoryUsage(), heapLimit: v8.getHeapStatistics().heap_size_limit },
cpu_load: os.loadavg(),
arch: os.arch(),
total_mem: os.totalmem(),