chore(scripts): remove one-off scripts nothing runs

Nothing in package.json, the workflows, the Dockerfile, the docs or the
other scripts named these: the bench result dumps of v1.44 and v1.45
that no document cites, the version-pinned release checks, the v1.42
correlation dry run, the read-only diagnostics and their cleanup and
conversion companions for defects fixed long ago, the one-off locale
builder from v1.4.25, and the four June seeders for the demo account.

Kept: the two bench results the benchmarks doc cites, the Google Health
sleep repair (the duplicate-night issue is still open), the demo
migration its password guard reads, the column-reader sweep its test
imports, and the message-bundle tools. The scripts README now lists the
kept tools that it did not name before and drops a reference to a file
that does not exist.
This commit is contained in:
Marc-André Bombeck committed 2026-11-11 22:16:47 +01:00
1 parent 9227844f42
commit 655a1d65a5
33 files changed
+23 -13254

No files matched your search

-254
View File
@@ -1,254 +0,0 @@
{
"meta": {
"label": "v1.44.0-baseline",
"commit": "d640eea32",
"date": "2026-10-22T03:54:05.746Z",
"node": "v22.23.2",
"postgres": "16.15",
"cpus": 14,
"loadAverage": [
9.4,
20.1,
20
],
"measurements": 1266549,
"iterations": 20,
"warmup": 3,
"heapMb": 792,
"idleStatementsPerSecond": 0,
"batch5k": {
"totalMs": 1722,
"totalStatements": 424
}
},
"results": [
{
"name": "/api/auth/me",
"mode": "cold",
"request": "GET /api/auth/me",
"n": 20,
"p50Ms": 12.1,
"p95Ms": 17.4,
"maxMs": 18.4,
"statementsMedian": 19,
"statementsMax": 19,
"failures": 0
},
{
"name": "/api/auth/me",
"mode": "warm",
"request": "GET /api/auth/me",
"n": 20,
"p50Ms": 16.6,
"p95Ms": 22.2,
"maxMs": 24.4,
"statementsMedian": 19,
"statementsMax": 19,
"failures": 0
},
{
"name": "dashboard summary",
"mode": "cold",
"request": "GET /api/dashboard/summary",
"n": 20,
"p50Ms": 205.6,
"p95Ms": 233.2,
"maxMs": 275.3,
"statementsMedian": 31,
"statementsMax": 32,
"failures": 0
},
{
"name": "dashboard summary",
"mode": "warm",
"request": "GET /api/dashboard/summary",
"n": 20,
"p50Ms": 12.8,
"p95Ms": 14.3,
"maxMs": 27.5,
"statementsMedian": 7,
"statementsMax": 7,
"failures": 0
},
{
"name": "dashboard snapshot",
"mode": "cold",
"request": "GET /api/dashboard/snapshot",
"n": 20,
"p50Ms": 2157.8,
"p95Ms": 2252.7,
"maxMs": 2292.9,
"statementsMedian": 158,
"statementsMax": 161,
"failures": 0
},
{
"name": "dashboard snapshot",
"mode": "warm",
"request": "GET /api/dashboard/snapshot",
"n": 20,
"p50Ms": 15.6,
"p95Ms": 23.5,
"maxMs": 25.6,
"statementsMedian": 13,
"statementsMax": 16,
"failures": 0
},
{
"name": "series pulse 30 d",
"mode": "cold",
"request": "GET /api/measurements/series?kind=pulse&days=30",
"n": 20,
"p50Ms": 50.8,
"p95Ms": 58.7,
"maxMs": 58.9,
"statementsMedian": 8,
"statementsMax": 9,
"failures": 0
},
{
"name": "series pulse 30 d",
"mode": "warm",
"request": "GET /api/measurements/series?kind=pulse&days=30",
"n": 20,
"p50Ms": 52.3,
"p95Ms": 59.5,
"maxMs": 59.9,
"statementsMedian": 8,
"statementsMax": 8,
"failures": 0
},
{
"name": "series pulse 365 d",
"mode": "cold",
"request": "GET /api/measurements/series?kind=pulse&days=365",
"n": 20,
"p50Ms": 289,
"p95Ms": 311.3,
"maxMs": 363.7,
"statementsMedian": 8,
"statementsMax": 9,
"failures": 0
},
{
"name": "series pulse 365 d",
"mode": "warm",
"request": "GET /api/measurements/series?kind=pulse&days=365",
"n": 20,
"p50Ms": 274.3,
"p95Ms": 355.8,
"maxMs": 366.8,
"statementsMedian": 8,
"statementsMax": 8,
"failures": 0
},
{
"name": "series pulse 3650 d",
"mode": "cold",
"request": "GET /api/measurements/series?kind=pulse&days=3650",
"n": 20,
"p50Ms": 1502.6,
"p95Ms": 2117.6,
"maxMs": 2122.9,
"statementsMedian": 8,
"statementsMax": 9,
"failures": 0
},
{
"name": "series pulse 3650 d",
"mode": "warm",
"request": "GET /api/measurements/series?kind=pulse&days=3650",
"n": 20,
"p50Ms": 1490.3,
"p95Ms": 1505.5,
"maxMs": 1555.2,
"statementsMedian": 8,
"statementsMax": 11,
"failures": 0
},
{
"name": "day view",
"mode": "cold",
"request": "GET /api/day/2026-10-21",
"n": 20,
"p50Ms": 61.7,
"p95Ms": 77.5,
"maxMs": 86.1,
"statementsMedian": 49,
"statementsMax": 50,
"failures": 0
},
{
"name": "day view",
"mode": "warm",
"request": "GET /api/day/2026-10-21",
"n": 20,
"p50Ms": 49,
"p95Ms": 55.6,
"maxMs": 62.5,
"statementsMedian": 48,
"statementsMax": 48,
"failures": 0
},
{
"name": "insights health status",
"mode": "cold",
"request": "GET /api/insights/health-status",
"n": 20,
"p50Ms": 124.1,
"p95Ms": 139.5,
"maxMs": 141.5,
"statementsMedian": 68,
"statementsMax": 68,
"failures": 0
},
{
"name": "insights health status",
"mode": "warm",
"request": "GET /api/insights/health-status",
"n": 20,
"p50Ms": 124.7,
"p95Ms": 157.8,
"maxMs": 165.3,
"statementsMedian": 68,
"statementsMax": 68,
"failures": 0
},
{
"name": "insights correlations",
"mode": "cold",
"request": "GET /api/insights/correlations",
"n": 20,
"p50Ms": 95.4,
"p95Ms": 105,
"maxMs": 108.8,
"statementsMedian": 45,
"statementsMax": 45,
"failures": 0
},
{
"name": "insights correlations",
"mode": "warm",
"request": "GET /api/insights/correlations",
"n": 20,
"p50Ms": 13,
"p95Ms": 15.4,
"maxMs": 15.9,
"statementsMedian": 8,
"statementsMax": 8,
"failures": 0
},
{
"name": "batch ingest 5k (per 500)",
"mode": "write",
"request": "POST /api/measurements/batch ×10",
"n": 10,
"p50Ms": 163,
"p95Ms": 220.7,
"maxMs": 220.7,
"statementsMedian": 42,
"statementsMax": 45,
"failures": 0
}
]
}
-25
View File
@@ -1,25 +0,0 @@
# Benchmark v1.44.0-baseline
Commit d640eea32, 2026-10-22T03:54:05.746Z. 1266549 measurement rows on the bench account, 20 measured requests per row after 3 warm-up requests, one at a time. Server: production build, web process, heap ceiling 792 MB. Postgres 16.15, 14 cores, load average 9.4,20.1,20 at the end. Idle background: 0 statements/s.
| Request | Mode | n | p50 ms | p95 ms | max ms | statements (median) | statements (max) |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: |
| /api/auth/me | cold | 20 | 12.1 | 17.4 | 18.4 | 19 | 19 |
| /api/auth/me | warm | 20 | 16.6 | 22.2 | 24.4 | 19 | 19 |
| dashboard summary | cold | 20 | 205.6 | 233.2 | 275.3 | 31 | 32 |
| dashboard summary | warm | 20 | 12.8 | 14.3 | 27.5 | 7 | 7 |
| dashboard snapshot | cold | 20 | 2157.8 | 2252.7 | 2292.9 | 158 | 161 |
| dashboard snapshot | warm | 20 | 15.6 | 23.5 | 25.6 | 13 | 16 |
| series pulse 30 d | cold | 20 | 50.8 | 58.7 | 58.9 | 8 | 9 |
| series pulse 30 d | warm | 20 | 52.3 | 59.5 | 59.9 | 8 | 8 |
| series pulse 365 d | cold | 20 | 289 | 311.3 | 363.7 | 8 | 9 |
| series pulse 365 d | warm | 20 | 274.3 | 355.8 | 366.8 | 8 | 8 |
| series pulse 3650 d | cold | 20 | 1502.6 | 2117.6 | 2122.9 | 8 | 9 |
| series pulse 3650 d | warm | 20 | 1490.3 | 1505.5 | 1555.2 | 8 | 11 |
| day view | cold | 20 | 61.7 | 77.5 | 86.1 | 49 | 50 |
| day view | warm | 20 | 49 | 55.6 | 62.5 | 48 | 48 |
| insights health status | cold | 20 | 124.1 | 139.5 | 141.5 | 68 | 68 |
| insights health status | warm | 20 | 124.7 | 157.8 | 165.3 | 68 | 68 |
| insights correlations | cold | 20 | 95.4 | 105 | 108.8 | 45 | 45 |
| insights correlations | warm | 20 | 13 | 15.4 | 15.9 | 8 | 8 |
| batch ingest 5k (per 500) | write | 10 | 163 | 220.7 | 220.7 | 42 | 45 |
File diff suppressed because it is too large. Load diff
-254
View File
@@ -1,254 +0,0 @@
{
"meta": {
"label": "v1.45.0-before",
"commit": "1915f9152",
"date": "2026-10-22T05:51:47.626Z",
"node": "v22.23.2",
"postgres": "16.15",
"cpus": 14,
"loadAverage": [
29.9,
21.9,
18.9
],
"measurements": 1265561,
"iterations": 20,
"warmup": 3,
"heapMb": 792,
"idleStatementsPerSecond": 0,
"batch5k": {
"totalMs": 1730,
"totalStatements": 534
}
},
"results": [
{
"name": "/api/auth/me",
"mode": "cold",
"request": "GET /api/auth/me",
"n": 20,
"p50Ms": 9.2,
"p95Ms": 11.6,
"maxMs": 13.3,
"statementsMedian": 19,
"statementsMax": 19,
"failures": 0
},
{
"name": "/api/auth/me",
"mode": "warm",
"request": "GET /api/auth/me",
"n": 20,
"p50Ms": 8.6,
"p95Ms": 10.5,
"maxMs": 13,
"statementsMedian": 19,
"statementsMax": 19,
"failures": 0
},
{
"name": "dashboard summary",
"mode": "cold",
"request": "GET /api/dashboard/summary",
"n": 20,
"p50Ms": 170.2,
"p95Ms": 220.5,
"maxMs": 228.3,
"statementsMedian": 31,
"statementsMax": 34,
"failures": 0
},
{
"name": "dashboard summary",
"mode": "warm",
"request": "GET /api/dashboard/summary",
"n": 20,
"p50Ms": 6,
"p95Ms": 6.7,
"maxMs": 6.8,
"statementsMedian": 7,
"statementsMax": 7,
"failures": 0
},
{
"name": "dashboard snapshot",
"mode": "cold",
"request": "GET /api/dashboard/snapshot",
"n": 20,
"p50Ms": 1481.8,
"p95Ms": 1526.2,
"maxMs": 1530,
"statementsMedian": 158,
"statementsMax": 161,
"failures": 0
},
{
"name": "dashboard snapshot",
"mode": "warm",
"request": "GET /api/dashboard/snapshot",
"n": 20,
"p50Ms": 7,
"p95Ms": 7.9,
"maxMs": 10.2,
"statementsMedian": 13,
"statementsMax": 13,
"failures": 0
},
{
"name": "series pulse 30 d",
"mode": "cold",
"request": "GET /api/measurements/series?kind=pulse&days=30",
"n": 20,
"p50Ms": 24.4,
"p95Ms": 30.8,
"maxMs": 31.1,
"statementsMedian": 8,
"statementsMax": 8,
"failures": 0
},
{
"name": "series pulse 30 d",
"mode": "warm",
"request": "GET /api/measurements/series?kind=pulse&days=30",
"n": 20,
"p50Ms": 20.5,
"p95Ms": 29.4,
"maxMs": 30.2,
"statementsMedian": 8,
"statementsMax": 9,
"failures": 0
},
{
"name": "series pulse 365 d",
"mode": "cold",
"request": "GET /api/measurements/series?kind=pulse&days=365",
"n": 20,
"p50Ms": 184.1,
"p95Ms": 192.6,
"maxMs": 201.1,
"statementsMedian": 8,
"statementsMax": 8,
"failures": 0
},
{
"name": "series pulse 365 d",
"mode": "warm",
"request": "GET /api/measurements/series?kind=pulse&days=365",
"n": 20,
"p50Ms": 178.1,
"p95Ms": 186.5,
"maxMs": 187.6,
"statementsMedian": 8,
"statementsMax": 8,
"failures": 0
},
{
"name": "series pulse 3650 d",
"mode": "cold",
"request": "GET /api/measurements/series?kind=pulse&days=3650",
"n": 20,
"p50Ms": 1627,
"p95Ms": 1664.5,
"maxMs": 1675.7,
"statementsMedian": 8,
"statementsMax": 9,
"failures": 0
},
{
"name": "series pulse 3650 d",
"mode": "warm",
"request": "GET /api/measurements/series?kind=pulse&days=3650",
"n": 20,
"p50Ms": 2090.9,
"p95Ms": 2435.4,
"maxMs": 2529.7,
"statementsMedian": 8,
"statementsMax": 9,
"failures": 0
},
{
"name": "day view",
"mode": "cold",
"request": "GET /api/day/2026-10-21",
"n": 20,
"p50Ms": 76.7,
"p95Ms": 93.6,
"maxMs": 116.2,
"statementsMedian": 49,
"statementsMax": 49,
"failures": 0
},
{
"name": "day view",
"mode": "warm",
"request": "GET /api/day/2026-10-21",
"n": 20,
"p50Ms": 62.8,
"p95Ms": 72,
"maxMs": 73.5,
"statementsMedian": 48,
"statementsMax": 48,
"failures": 0
},
{
"name": "insights health status",
"mode": "cold",
"request": "GET /api/insights/health-status",
"n": 20,
"p50Ms": 244.7,
"p95Ms": 401.2,
"maxMs": 404.1,
"statementsMedian": 68,
"statementsMax": 69,
"failures": 0
},
{
"name": "insights health status",
"mode": "warm",
"request": "GET /api/insights/health-status",
"n": 20,
"p50Ms": 238.9,
"p95Ms": 399.1,
"maxMs": 476.6,
"statementsMedian": 68,
"statementsMax": 68,
"failures": 0
},
{
"name": "insights correlations",
"mode": "cold",
"request": "GET /api/insights/correlations",
"n": 20,
"p50Ms": 105.6,
"p95Ms": 326.9,
"maxMs": 349.7,
"statementsMedian": 49,
"statementsMax": 52,
"failures": 0
},
{
"name": "insights correlations",
"mode": "warm",
"request": "GET /api/insights/correlations",
"n": 20,
"p50Ms": 11.3,
"p95Ms": 16.6,
"maxMs": 20.3,
"statementsMedian": 8,
"statementsMax": 8,
"failures": 0
},
{
"name": "batch ingest 5k (per 500)",
"mode": "write",
"request": "POST /api/measurements/batch ×10",
"n": 10,
"p50Ms": 166.1,
"p95Ms": 220.3,
"maxMs": 220.3,
"statementsMedian": 53,
"statementsMax": 56,
"failures": 0
}
]
}
-25
View File
@@ -1,25 +0,0 @@
# Benchmark v1.45.0-before
Commit 1915f9152 (the v1.44 runtime this branch starts from), 2026-10-22T05:51:47.626Z. 1265561 measurement rows on the bench account, 20 measured requests per row after 3 warm-up requests, one at a time. Server: production build, web process, heap ceiling 792 MB. Postgres 16.15, 14 cores, load average 29.9,21.9,18.9 at the end. Idle background: 0 statements/s.
| Request | Mode | n | p50 ms | p95 ms | max ms | statements (median) | statements (max) |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: |
| /api/auth/me | cold | 20 | 9.2 | 11.6 | 13.3 | 19 | 19 |
| /api/auth/me | warm | 20 | 8.6 | 10.5 | 13 | 19 | 19 |
| dashboard summary | cold | 20 | 170.2 | 220.5 | 228.3 | 31 | 34 |
| dashboard summary | warm | 20 | 6 | 6.7 | 6.8 | 7 | 7 |
| dashboard snapshot | cold | 20 | 1481.8 | 1526.2 | 1530 | 158 | 161 |
| dashboard snapshot | warm | 20 | 7 | 7.9 | 10.2 | 13 | 13 |
| series pulse 30 d | cold | 20 | 24.4 | 30.8 | 31.1 | 8 | 8 |
| series pulse 30 d | warm | 20 | 20.5 | 29.4 | 30.2 | 8 | 9 |
| series pulse 365 d | cold | 20 | 184.1 | 192.6 | 201.1 | 8 | 8 |
| series pulse 365 d | warm | 20 | 178.1 | 186.5 | 187.6 | 8 | 8 |
| series pulse 3650 d | cold | 20 | 1627 | 1664.5 | 1675.7 | 8 | 9 |
| series pulse 3650 d | warm | 20 | 2090.9 | 2435.4 | 2529.7 | 8 | 9 |
| day view | cold | 20 | 76.7 | 93.6 | 116.2 | 49 | 49 |
| day view | warm | 20 | 62.8 | 72 | 73.5 | 48 | 48 |
| insights health status | cold | 20 | 244.7 | 401.2 | 404.1 | 68 | 69 |
| insights health status | warm | 20 | 238.9 | 399.1 | 476.6 | 68 | 68 |
| insights correlations | cold | 20 | 105.6 | 326.9 | 349.7 | 49 | 52 |
| insights correlations | warm | 20 | 11.3 | 16.6 | 20.3 | 8 | 8 |
| batch ingest 5k (per 500) | write | 10 | 166.1 | 220.3 | 220.3 | 53 | 56 |
File diff suppressed because it is too large. Load diff
-298
View File
@@ -1,298 +0,0 @@
# Boot profile v1.45.0-boot-after
Commit a859adb59, 2026-10-22T04:49:50.419Z. Production build, every role, heap ceiling 792 MB, 300 s idle. 14 cores, load average 8.6,9.4,10.7 at the end.
- first answer from /api/health: 850 ms; background role ready: 3038 ms
- event-loop stalls logged: 0, max 0 ms
## Stalls
## Heap samples
| at s | used MB | old | large obj | code | external | array buffers | rss |
| ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 6 | 166 | 91 | 53 | 3 | 12 | 1 | 430 |
| 306 | 153 | 90 | 53 | 4 | 11 | 0 | 599 |
## Full collections (mark-compact)
10 mark-compacts during the run. Used heap before the collection, and what survived it (the live heap):
| at s | before MB | after MB |
| ---: | ---: | ---: |
| 0 | 20.2 | 17.1 |
| 0 | 55.3 | 52.6 |
| 0 | 83.2 | 81.1 |
| 1 | 148.4 | 132.7 |
| 16 | 159.6 | 153.2 |
| 17 | 153.4 | 151 |
| 62 | 167.5 | 157.5 |
| 246 | 183.4 | 152.6 |
| 303 | 165.6 | 151.8 |
| 303 | 151.8 | 151.8 |
## Main-thread busy stretches over 50 ms without an idle sample, first two minutes
### at 6 ms, 175 ms
| self time by module | ms |
| --- | ---: |
| npm:next | 47.2 |
| node:internal/modules/cjs/loader | 34.8 |
| (native) | 34.5 |
| node:internal/bootstrap/realm | 25.7 |
| node:internal/deps/undici/undici | 8.8 |
| node:path | 6.3 |
| node:internal/modules/package_json_reader | 3 |
| node:internal/net | 3 |
| node:internal/modules/esm/resolve | 2.5 |
| node:fs | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
### at 203 ms, 241 ms
| self time by module | ms |
| --- | ---: |
| (native) | 52.7 |
| node:internal/modules/cjs/loader | 40.1 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 31.7 |
| wasm://wasm/00d1cb12 | 28.7 |
| npm:@prisma/client | 28 |
| npm:next | 16.3 |
| node:internal/modules/esm/utils | 12 |
| node:fs | 4.5 |
| npm:zod | 3 |
| node:internal/modules/helpers | 3 |
| inclusive, application modules | ms |
| --- | ---: |
| src/instrumentation.ts | 80.8 |
| src/lib/db-session.ts | 49.5 |
| src/lib/boot/startup-state.ts | 25.6 |
| src/lib/boot/boot-steps.ts | 25.6 |
| src/lib/logging/background.ts | 25.6 |
| src/lib/process-type.ts | 25.5 |
| src/lib/logging/context.ts | 13.6 |
| src/lib/validations/measurement.ts | 12.1 |
| src/lib/logging/redact.ts | 10.5 |
| src/lib/validations/entry-instant.ts | 4.6 |
### at 501 ms, 178 ms
| self time by module | ms |
| --- | ---: |
| node:internal/modules/cjs/loader | 53.9 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 37.5 |
| npm:next | 18 |
| npm:zod | 12 |
| node:internal/modules/esm/utils | 10.5 |
| (native) | 8.7 |
| node:fs | 6 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 4.5 |
| npm:undici | 4.5 |
| node:internal/url | 1.8 |
| inclusive, application modules | ms |
| --- | ---: |
| src/app/api/health/route.ts | 61.4 |
| src/lib/api-errors.ts | 27 |
| src/lib/jobs/job-failures.ts | 14.9 |
| src/lib/jobs/offhost-backup.ts | 14.9 |
| src/lib/managed-profiles/handover-access.ts | 14.9 |
| src/lib/sharing/acting-session.ts | 14.9 |
| src/lib/db-session.ts | 13.4 |
| src/lib/export/environment-backup.ts | 13.4 |
| src/lib/export/full-backup-payload.ts | 13.4 |
| src/lib/logging/background.ts | 10.5 |
### at 833 ms, 184 ms
| self time by module | ms |
| --- | ---: |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 38.9 |
| node:internal/modules/cjs/loader | 28.6 |
| (native) | 22.8 |
| src/lib/i18n/server-catalogs.ts | 15.1 |
| npm:yaml | 15 |
| node:fs | 12.1 |
| npm:zod | 9 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 5.9 |
| turbopack:///[turbopack]/shared/runtime/runtime-utils.ts | 4.5 |
| npm:semver | 3 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/jobs/reminder-worker.ts | 129.1 |
| src/lib/jobs/reminder/google-health-sync.ts | 88.5 |
| src/lib/whoop/sync.ts | 79.5 |
| src/lib/whoop/sync-body.ts | 63 |
| src/lib/insights/bucket-series.ts | 60 |
| src/lib/whoop/oauth-descriptor.ts | 60 |
| src/lib/whoop/sync-core.ts | 60 |
| src/instrumentation.ts | 43.4 |
| src/lib/import/unzip-export-xml.ts | 31.4 |
| src/lib/jobs/integration-status-null-probe.ts | 31.4 |
### at 1099 ms, 54 ms
| self time by module | ms |
| --- | ---: |
| node:internal/modules/cjs/loader | 23.9 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 10.6 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 5.8 |
| src/lib/daily/today-overview.ts | 4.5 |
| src/lib/jobs/reminder-worker.ts | 3 |
| node:fs | 3 |
| npm:pg-boss | 1.5 |
| npm:zod | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/jobs/reminder-worker.ts | 52.3 |
| src/lib/jobs/reminder/insights-handlers.ts | 22.3 |
| src/lib/ai/prompts/arrival-reaction.ts | 12 |
| src/lib/daily/score-steady.ts | 10.5 |
| src/lib/dashboard/bands.ts | 6 |
| src/lib/jobs/data-arrival.ts | 4.5 |
| src/lib/dashboard/snapshot-read.ts | 4.5 |
| src/lib/daily/today-overview.ts | 4.5 |
| src/lib/daily/priority-item-key.ts | 4.5 |
| src/lib/ai/prompts/status-batch.ts | 3 |
### at 1309 ms, 51 ms
| self time by module | ms |
| --- | ---: |
| node:internal/modules/cjs/loader | 28 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 6 |
| node:fs | 4.5 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 3 |
| turbopack:///[turbopack]/nodejs/runtime/runtime-base.ts | 1.5 |
| src/lib/jobs/failure-condition.ts | 1.5 |
| src/lib/labs/parse-reference-range.ts | 1.5 |
| npm:zod | 1.5 |
| node:internal/linkedlist | 1.5 |
| (native) | 0.9 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/jobs/reminder-worker.ts | 48.2 |
| src/lib/jobs/reminder/ops-handlers.ts | 14.1 |
| src/lib/medications/ingredients/label-extract.ts | 3 |
| src/lib/export/restore-backup.ts | 2.1 |
| src/lib/jobs/failure-condition.ts | 1.5 |
| src/lib/documents/ai-runs/summary-run.ts | 1.5 |
| src/lib/documents/auto-stage-labs.ts | 1.5 |
| src/lib/documents/ai-runs/store.ts | 1.5 |
| src/lib/labs/parse-reference-range.ts | 1.5 |
| src/lib/labs/ocr-upload.ts | 1.5 |
## Self time by module until the worker is ready
| module | ms |
| --- | ---: |
| (native) | 230.8 |
| node:internal/modules/cjs/loader | 223.6 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 124.7 |
| npm:next | 98.8 |
| wasm://wasm/00d1cb12 | 62.6 |
| npm:@prisma/client | 56.2 |
| node:fs | 34.6 |
| node:internal/bootstrap/realm | 28.7 |
| npm:pg | 28.3 |
| npm:zod | 27 |
| npm:pg-boss | 24.6 |
| node:internal/modules/esm/utils | 22.5 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 20.6 |
| npm:luxon | 17 |
| src/lib/i18n/server-catalogs.ts | 15.1 |
| npm:yaml | 15 |
| npm:pg-pool | 13 |
| node:internal/deps/undici/undici | 10.4 |
| node:path | 7.8 |
| turbopack:///[turbopack]/shared/runtime/runtime-utils.ts | 7.5 |
| node:internal/async_hooks | 7.5 |
| node:internal/process/task_queues | 7.3 |
| node:internal/modules/package_json_reader | 6 |
| npm:undici | 6 |
| npm:pg-protocol | 6 |
## Heap snapshot after 300 s idle (live heap after a full GC)
160.1 MB in 1275329 nodes; module source strings over 50 KB: 39.8 MB.
- parsed locale catalogs: 8 objects, 7 MB retained
| node type | MB |
| --- | ---: |
| string | 68.7 |
| array | 26.4 |
| code | 21.1 |
| object | 14.1 |
| hidden | 8.9 |
| native | 8 |
| object shape | 5.9 |
| closure | 5.2 |
| concatenated string | 1.3 |
| regexp | 0.2 |
| sliced string | 0.2 |
| number | 0.1 |
| synthetic | 0 |
| symbol | 0 |
| bigint | 0 |
| constructor | MB | count |
| --- | ---: | ---: |
| array:(object elements) | 20.4 | 23797 |
| object:Object | 10.2 | 274231 |
| native:system / JSArrayBufferData | 7.6 | 171 |
| array:(object properties) | 3.6 | 6512 |
| array: | 2.4 | 10502 |
| closure: | 1.6 | 29042 |
| object:system / Context | 1.6 | 28873 |
| closure:native_bind | 1 | 20782 |
| object:Array | 0.6 | 19679 |
| object:a | 0.4 | 4438 |
| native:Node / histogram | 0.4 | 1 |
| closure:get | 0.3 | 4736 |
| object:d | 0.3 | 4425 |
| object:Set | 0.2 | 5673 |
| closure:set | 0.2 | 3432 |
| object:Module | 0.2 | 1958 |
| closure:i | 0.1 | 1581 |
| closure:n | 0.1 | 1572 |
| object:Promise | 0.1 | 1277 |
| object:n | 0.1 | 1881 |
| largest retained subtrees | MB | retaining path |
| --- | ---: | --- |
| object:t | 33.9 | [1] > [10] > 60 > extension > global > prisma > [1] |
| object:global | 7.9 | [1] > [10] > 60 > extension |
| object:system / Context | 7.4 | Node / PrincipalRealm > base_object_list > Node / BaseObjectList > [25] > Node / ModuleWrap > native_to_javascript > ModuleWrap > 2 > [4] > context |
| object:Module | 5.6 | [1] > [10] > 97 > process > nextTick > patchedNextTick > context > system / Context > require > require > cache > .n |
| code:.next/server/chu | 5.6 | require > cache > Object > .next/server/chunks/_1kwfnjg._.js > Module > exports > Array > [1] > > shared > script |
| code:.next/server/chu | 5.6 | global > prisma > [1] > t > _engineConfig > Object > compilerWasm > Object > getRuntime > getRuntime > shared > script |
| object:Generator | 4.4 | [6] > principal_realm > Node / PrincipalRealm > base_object_list > Node / BaseObjectList > [26] > Node / ModuleWrap > native_to_javascript > ModuleWrap > 2 > [4 |
| string:AGFzbQEAAAABtgRLYAN/f38Bf2ACf38Bf2ACf38AYAF/AGADf39/AGAEf39/ | 4.4 | [1] > [21] > 62203 |
| object:Object | 3.3 | system / Context > require > require > cache > Object > .next/server/chunks/[turbopack]_runtime.js > Module > export |
| largest strings | MB |
| --- | ---: |
| module.exports=[234494,A=>{"use strict";var e,C,g,I,Q=Object.defineProperty,B={},s={$:()=> | 5.6 |
| module.exports=[17856,A=>{"use strict";var e,C,g,I,Q=Object.defineProperty,B={},s={$:()=>i | 5.6 |
| module.exports=[17856,A=>{"use strict";var e,C,g,I,Q=Object.defineProperty,B={},s={$:()=>i | 5.6 |
| const wasm = "AGFzbQEAAAABtgRLYAN/f38Bf2ACf38Bf2ACf38AYAF/AGADf39/AGAEf39/fwBgBX9/f39/AGAB | 4.4 |
| AGFzbQEAAAABtgRLYAN/f38Bf2ACf38Bf2ACf38AYAF/AGADf39/AGAEf39/fwBgBX9/f39/AGABfwF/YAZ/f39/f3 | 4.4 |
| lliADOAUngIEAACgKwAgBgAAoSsAIAcAAKErACAIAACiKwAgCQAAoysAIAoAAKQrACALAAClKwAgDAAApisAIA0AAK | 1.9 |
| (()=>{var e,t,r={"./dist/build/webpack/alias/react-dom-server.js"(e,t,r){"use strict";var | 1.3 |
| module.exports=[842865,(e,t,r)=>{let i=e.r(522734);t.exports=function(e){return e?/-----BE | 1.2 |
| module.exports=[842865,(e,t,r)=>{let i=e.r(522734);t.exports=function(e){return e?/-----BE | 1.2 |
| module.exports=[799092,(e,t,n)=>{"use strict";Object.defineProperty(n,"__esModule",{value: | 1.1 |
| // v1.4.34 web-freeze. Schema is locked additive-only until iOS launch // + v1.5.0 marker. | 1.1 |
| module.exports=[971743,(A,e,t)=>{"use strict";let r=A.r(57328),{addAbortListener:s}=A.r(68 | 1.1 |
| module.exports=[835717,(A,e,t)=>{"use strict";let r=A.r(57328),{addAbortListener:s}=A.r(68 | 1 |
| module.exports=[767189,e=>e.a(async(t,a)=>{try{var n=e.i(64105),r=e.i(563616),i=t([n]);[n] | 0.8 |
| module.exports=[594108,806176,674750,98746,t=>{"use strict";var i;let r;function n(t){retu | 0.7 |
File diff suppressed because it is too large. Load diff
-804
View File
@@ -1,804 +0,0 @@
# Boot profile v1.45.0-boot-final
Commit a57fa8335, 2026-10-22T06:58:52.591Z. Production build, every role, heap ceiling 792 MB, 300 s idle. 14 cores, load average 5.6,6.4,11.1 at the end.
- first answer from /api/health: 1325 ms; background role ready: 3217 ms
- event-loop stalls logged: 0, max 0 ms
## Stalls
## Heap samples
| at s | used MB | old | large obj | code | external | array buffers | rss |
| ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 6 | 225 | 158 | 54 | 4 | 11 | 0 | 500 |
| 306 | 158 | 96 | 53 | 5 | 11 | 0 | 788 |
## Full collections (mark-compact)
98 mark-compacts during the run. Used heap before the collection, and what survived it (the live heap):
| at s | before MB | after MB |
| ---: | ---: | ---: |
| 0 | 21.5 | 17.5 |
| 8 | 203.8 | 146.5 |
| 24 | 236.5 | 142.5 |
| 41 | 223.8 | 144.9 |
| 60 | 225.8 | 147.5 |
| 85 | 224.4 | 147.7 |
| 124 | 225.4 | 151.2 |
| 167 | 176.7 | 151 |
| 209 | 230.1 | 150.4 |
| 242 | 197.9 | 151.5 |
| 273 | 224.8 | 152.2 |
| 302 | 177.9 | 152.5 |
| 312 | 170.5 | 152.9 |
| 327 | 170.6 | 152 |
| 338 | 169.7 | 151.8 |
## Main-thread busy stretches over 50 ms without an idle sample, first two minutes
### at 5 ms, 396 ms
| self time by module | ms |
| --- | ---: |
| (native) | 230.2 |
| node:internal/modules/cjs/loader | 57.8 |
| npm:next | 52.3 |
| node:internal/bootstrap/realm | 29.3 |
| node:internal/deps/undici/undici | 8.9 |
| node:internal/modules/esm/loader | 4.5 |
| node:fs | 3 |
| node:internal/net | 2.5 |
| node:internal/bootstrap/switches/is_main_thread | 2 |
| node:os | 1.8 |
| inclusive, application modules | ms |
| --- | ---: |
### at 472 ms, 336 ms
| self time by module | ms |
| --- | ---: |
| (native) | 121.3 |
| wasm://wasm/00d1cb12 | 43 |
| node:internal/modules/cjs/loader | 40.5 |
| npm:next | 31.7 |
| npm:@prisma/client | 23.8 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 23.4 |
| node:internal/modules/esm/utils | 17.3 |
| npm:zod | 5.9 |
| turbopack:///[turbopack]/shared/runtime/runtime-utils.ts | 3 |
| node:vm | 1.7 |
| inclusive, application modules | ms |
| --- | ---: |
| src/instrumentation.ts | 95.8 |
| src/lib/db-session.ts | 47.3 |
| src/lib/process-type.ts | 27.1 |
| src/lib/boot/startup-state.ts | 25.5 |
| src/lib/boot/boot-steps.ts | 25.5 |
| src/lib/logging/background.ts | 25.5 |
| src/lib/logging/redact.ts | 13 |
| src/lib/logging/context.ts | 11 |
| src/lib/validations/measurement.ts | 10 |
| src/generated/prisma/internal/class.ts | 4.7 |
### at 811 ms, 225 ms
| self time by module | ms |
| --- | ---: |
| node:internal/modules/cjs/loader | 52.3 |
| (native) | 48.2 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 37 |
| npm:next | 22.2 |
| npm:zod | 12.5 |
| node:internal/modules/esm/utils | 8.7 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 5.6 |
| node:fs | 4.5 |
| node:internal/async_hooks | 3 |
| node:internal/modules/esm/translators | 2.6 |
| inclusive, application modules | ms |
| --- | ---: |
| src/app/api/health/route.ts | 62 |
| src/lib/api-errors.ts | 25.9 |
| src/lib/auth/secure-cookie.ts | 14.9 |
| src/lib/logging/background.ts | 13.4 |
| src/lib/sharing/acting-session.ts | 12.8 |
| src/lib/validations/measurement.ts | 11.9 |
| src/lib/db-session.ts | 11.3 |
| src/lib/export/environment-backup.ts | 11.3 |
| src/lib/export/full-backup-payload.ts | 11.3 |
| src/lib/jobs/job-failures.ts | 11.3 |
### at 1063 ms, 246 ms
| self time by module | ms |
| --- | ---: |
| (native) | 64.7 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 47.2 |
| node:internal/modules/cjs/loader | 31.6 |
| npm:luxon | 18 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 15.3 |
| npm:yaml | 15 |
| npm:zod | 10.2 |
| src/lib/i18n/server-catalogs.ts | 8.2 |
| turbopack:///[turbopack]/shared/runtime/runtime-utils.ts | 4.5 |
| npm:cron-parser | 4 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/jobs/reminder-worker.ts | 137.6 |
| src/lib/jobs/reminder/google-health-sync.ts | 78 |
| src/lib/whoop/sync.ts | 65.9 |
| src/instrumentation.ts | 53.8 |
| src/lib/insights/bucket-series.ts | 47.1 |
| src/lib/whoop/oauth-descriptor.ts | 47.1 |
| src/lib/whoop/sync-core.ts | 47.1 |
| src/lib/whoop/sync-body.ts | 47.1 |
| src/lib/import/unzip-export-xml.ts | 35.3 |
| src/lib/jobs/integration-status-null-probe.ts | 35.3 |
### at 1363 ms, 68 ms
| self time by module | ms |
| --- | ---: |
| node:internal/modules/cjs/loader | 29.2 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 6.7 |
| (native) | 5.9 |
| turbopack:///[turbopack]/shared/runtime/runtime-utils.ts | 4.5 |
| src/lib/daily/today-overview.ts | 4.1 |
| node:fs | 3 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 3 |
| node:internal/streams/writable | 1.5 |
| src/lib/jobs/reminder/insights-handlers.ts | 1.5 |
| npm:next | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/jobs/reminder-worker.ts | 62.5 |
| src/lib/jobs/reminder/insights-handlers.ts | 24.4 |
| src/lib/ai/prompts/arrival-reaction.ts | 12.8 |
| src/lib/daily/score-steady.ts | 11.3 |
| src/lib/dashboard/bands.ts | 7.1 |
| src/lib/dashboard/snapshot-read.ts | 5.8 |
| src/lib/jobs/data-arrival.ts | 4.5 |
| src/lib/daily/today-overview.ts | 4.1 |
| src/lib/daily/priority-item-key.ts | 4.1 |
| src/lib/ai/prompts/status-batch.ts | 3 |
### at 1545 ms, 57 ms
| self time by module | ms |
| --- | ---: |
| node:internal/modules/cjs/loader | 25.3 |
| (native) | 12.9 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 7.2 |
| node:fs | 4.2 |
| node:buffer | 1.5 |
| npm:zod | 1.5 |
| src/lib/jobs/pr-detection.ts | 1.5 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 1.5 |
| src/lib/jobs/measurement-maintenance.ts | 1.3 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/jobs/reminder-worker.ts | 55.3 |
| src/lib/jobs/reminder/ops-handlers.ts | 13 |
| src/lib/export/restore-backup.ts | 3 |
| src/lib/medications/ingredients/label-extract.ts | 3 |
| src/lib/environment/service.ts | 1.5 |
| src/lib/export/backup-blob.ts | 1.5 |
| src/lib/jobs/pr-detection.ts | 1.5 |
| src/lib/jobs/document-content-index-backfill.ts | 1.5 |
| src/lib/labs/ocr-extract.ts | 1.5 |
| src/lib/jobs/reminder/backup-handlers.ts | 1.5 |
### at 1820 ms, 114 ms
| self time by module | ms |
| --- | ---: |
| src/lib/tz/zone-offset.ts | 36 |
| npm:@prisma/client | 18.2 |
| src/lib/validations/source-priority.ts | 18.1 |
| (native) | 13.1 |
| src/lib/personal-records/pr-detection-worker.ts | 7.2 |
| node:buffer | 4.1 |
| src/lib/analytics/source-priority.ts | 3.7 |
| npm:zod | 2.3 |
| npm:pg | 2 |
| src/lib/tz/format.ts | 1.9 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 73.3 |
| src/lib/tz/format.ts | 40.7 |
| src/lib/measurements/consolidation-tz.ts | 40.7 |
| src/lib/tz/zone-offset.ts | 38.8 |
| src/lib/measurements/consolidation-base.ts | 38.1 |
| src/lib/analytics/source-priority.ts | 28.1 |
| src/lib/validations/source-priority.ts | 20.4 |
| src/lib/tz/intl-cache.ts | 1.5 |
### at 2407 ms, 50 ms
| self time by module | ms |
| --- | ---: |
| (native) | 18.9 |
| src/lib/validations/source-priority.ts | 14.1 |
| src/lib/analytics/source-priority.ts | 3.7 |
| src/lib/personal-records/pr-detection-worker.ts | 3 |
| npm:next | 1.8 |
| npm:%40prisma | 1.5 |
| src/lib/tz/format.ts | 1.5 |
| node:internal/async_local_storage/async_hooks | 1.5 |
| npm:pg | 1.5 |
| npm:@prisma/client | 1.3 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 26.6 |
| src/lib/analytics/source-priority.ts | 19.3 |
| src/lib/validations/source-priority.ts | 14.1 |
| src/lib/tz/format.ts | 3 |
| src/lib/measurements/consolidation-tz.ts | 3 |
| src/lib/measurements/consolidation-base.ts | 2.8 |
| src/lib/tz/zone-offset.ts | 1.5 |
### at 18192 ms, 59 ms
| self time by module | ms |
| --- | ---: |
| (native) | 15.5 |
| npm:@prisma/client | 13.9 |
| src/lib/validations/source-priority.ts | 11.8 |
| npm:pg | 3.6 |
| node:events | 3 |
| node:buffer | 2.5 |
| src/lib/measurements/consolidation-base.ts | 1.5 |
| src/lib/personal-records/pr-detection-worker.ts | 1.5 |
| node:internal/async_hooks | 1.5 |
| npm:pg-types | 1.4 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 18.9 |
| src/lib/analytics/source-priority.ts | 12.9 |
| src/lib/validations/source-priority.ts | 11.8 |
| src/lib/measurements/consolidation-base.ts | 4.5 |
| src/lib/tz/zone-offset.ts | 2.6 |
| src/lib/tz/format.ts | 2.6 |
| src/lib/measurements/consolidation-tz.ts | 2.6 |
### at 19914 ms, 65 ms
| self time by module | ms |
| --- | ---: |
| src/lib/validations/source-priority.ts | 18.1 |
| (native) | 12.3 |
| npm:@prisma/client | 11.6 |
| npm:next | 5.9 |
| src/lib/personal-records/pr-detection-worker.ts | 3 |
| src/lib/tz/format.ts | 3 |
| npm:pg | 2.6 |
| npm:pg-protocol | 2.5 |
| node:internal/async_hooks | 1.5 |
| src/lib/analytics/source-priority.ts | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 29.8 |
| src/lib/analytics/source-priority.ts | 22.6 |
| src/lib/validations/source-priority.ts | 18.1 |
| src/lib/tz/format.ts | 5.8 |
| src/lib/measurements/consolidation-tz.ts | 5.8 |
| src/lib/tz/zone-offset.ts | 2.8 |
| src/lib/measurements/consolidation-base.ts | 2.8 |
### at 20296 ms, 55 ms
| self time by module | ms |
| --- | ---: |
| (native) | 22.4 |
| npm:@prisma/client | 14.8 |
| node:buffer | 3 |
| npm:zod | 3 |
| src/lib/measurements/consolidation-base.ts | 3 |
| src/lib/tz/format.ts | 1.5 |
| node:internal/stream_base_commons | 1.5 |
| src/lib/analytics/source-priority.ts | 1.5 |
| src/lib/personal-records/pr-detection-worker.ts | 1.5 |
| npm:pg-protocol | 1.3 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 10.5 |
| src/lib/analytics/source-priority.ts | 6 |
| src/lib/validations/source-priority.ts | 3 |
| src/lib/measurements/consolidation-base.ts | 3 |
| src/lib/tz/format.ts | 1.5 |
| src/lib/measurements/consolidation-tz.ts | 1.5 |
### at 30289 ms, 69 ms
| self time by module | ms |
| --- | ---: |
| src/lib/validations/source-priority.ts | 18.3 |
| (native) | 12.9 |
| npm:@prisma/client | 8.8 |
| node:buffer | 6.8 |
| src/lib/personal-records/pr-detection-worker.ts | 4.5 |
| src/lib/tz/format.ts | 4 |
| npm:pg-protocol | 3 |
| npm:zod | 3 |
| node:timers | 1.5 |
| node:internal/async_hooks | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 33 |
| src/lib/analytics/source-priority.ts | 24.3 |
| src/lib/validations/source-priority.ts | 21.3 |
| src/lib/tz/format.ts | 5.6 |
| src/lib/measurements/consolidation-tz.ts | 5.6 |
| src/lib/measurements/consolidation-base.ts | 2.6 |
| src/lib/tz/zone-offset.ts | 1.5 |
### at 31004 ms, 68 ms
| self time by module | ms |
| --- | ---: |
| (native) | 17.8 |
| src/lib/validations/source-priority.ts | 14.9 |
| npm:@prisma/client | 7.6 |
| npm:next | 4.5 |
| node:internal/async_hooks | 4.5 |
| npm:pg-protocol | 4.1 |
| npm:pg | 3 |
| src/lib/tz/zone-offset.ts | 3 |
| node:buffer | 2.7 |
| src/lib/analytics/source-priority.ts | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 26.4 |
| src/lib/analytics/source-priority.ts | 19 |
| src/lib/validations/source-priority.ts | 16.2 |
| src/lib/measurements/consolidation-base.ts | 6.1 |
| src/lib/tz/format.ts | 5.8 |
| src/lib/measurements/consolidation-tz.ts | 5.8 |
| src/lib/tz/zone-offset.ts | 4.5 |
### at 35350 ms, 65 ms
| self time by module | ms |
| --- | ---: |
| src/lib/validations/source-priority.ts | 17 |
| npm:@prisma/client | 11.8 |
| (native) | 8.6 |
| node:buffer | 6.5 |
| src/lib/tz/format.ts | 4.5 |
| npm:pg-protocol | 3 |
| src/lib/personal-records/pr-detection-worker.ts | 3 |
| npm:%40prisma | 1.6 |
| npm:pg | 1.5 |
| src/lib/analytics/source-priority.ts | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 26 |
| src/lib/analytics/source-priority.ts | 20 |
| src/lib/validations/source-priority.ts | 17 |
| src/lib/tz/format.ts | 4.5 |
| src/lib/measurements/consolidation-tz.ts | 4.5 |
| src/lib/measurements/consolidation-base.ts | 3 |
### at 36452 ms, 57 ms
| self time by module | ms |
| --- | ---: |
| (native) | 20 |
| src/lib/validations/source-priority.ts | 16 |
| npm:@prisma/client | 7.3 |
| node:internal/per_context/primordials | 2.8 |
| npm:%40prisma | 1.5 |
| npm:next | 1.5 |
| src/lib/tz/zone-offset.ts | 1.5 |
| node:internal/async_hooks | 1.5 |
| node:internal/streams/readable | 1.5 |
| npm:pg-protocol | 1.2 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 21.2 |
| src/lib/validations/source-priority.ts | 16 |
| src/lib/analytics/source-priority.ts | 16 |
| src/lib/tz/format.ts | 2.5 |
| src/lib/measurements/consolidation-tz.ts | 2.5 |
| src/lib/measurements/consolidation-base.ts | 2.5 |
| src/lib/tz/zone-offset.ts | 1.5 |
### at 38744 ms, 56 ms
| self time by module | ms |
| --- | ---: |
| src/lib/validations/source-priority.ts | 13.3 |
| (native) | 9.9 |
| npm:@prisma/client | 9.2 |
| node:buffer | 4.7 |
| npm:pg-protocol | 4.3 |
| node:events | 1.9 |
| npm:pg | 1.6 |
| npm:%40prisma | 1.5 |
| npm:next | 1.5 |
| src/lib/tz/format.ts | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 21.8 |
| src/lib/analytics/source-priority.ts | 16 |
| src/lib/validations/source-priority.ts | 13.3 |
| src/lib/measurements/consolidation-base.ts | 4.3 |
| src/lib/tz/format.ts | 3 |
| src/lib/measurements/consolidation-tz.ts | 3 |
| src/lib/tz/zone-offset.ts | 1.4 |
### at 42458 ms, 50 ms
| self time by module | ms |
| --- | ---: |
| npm:@prisma/client | 13.5 |
| src/lib/validations/source-priority.ts | 10.1 |
| (native) | 7.6 |
| npm:pg-protocol | 3.2 |
| node:events | 3 |
| src/lib/personal-records/pr-detection-worker.ts | 3 |
| src/lib/tz/format.ts | 3 |
| npm:pg | 2.8 |
| node:internal/async_hooks | 1.5 |
| npm:%40prisma | 1.4 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 17.3 |
| src/lib/analytics/source-priority.ts | 12.7 |
| src/lib/validations/source-priority.ts | 10.1 |
| src/lib/tz/format.ts | 3 |
| src/lib/measurements/consolidation-tz.ts | 3 |
| src/lib/measurements/consolidation-base.ts | 1.5 |
| src/lib/jobs/job-lock.ts | 1.3 |
| src/lib/jobs/long-pass.ts | 1.3 |
| src/lib/jobs/run-job.ts | 1.3 |
| src/lib/jobs/job-observer.ts | 1.3 |
### at 45451 ms, 63 ms
| self time by module | ms |
| --- | ---: |
| src/lib/validations/source-priority.ts | 15.8 |
| npm:@prisma/client | 10.5 |
| (native) | 8.4 |
| src/lib/tz/format.ts | 5.3 |
| node:internal/async_local_storage/async_hooks | 4.4 |
| node:buffer | 3 |
| npm:pg | 3 |
| src/lib/personal-records/pr-detection-worker.ts | 3 |
| npm:zod | 3 |
| npm:%40prisma | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 31.7 |
| src/lib/analytics/source-priority.ts | 21.8 |
| src/lib/validations/source-priority.ts | 18.8 |
| src/lib/measurements/consolidation-base.ts | 5.3 |
| src/lib/tz/format.ts | 5.3 |
| src/lib/measurements/consolidation-tz.ts | 5.3 |
### at 56854 ms, 66 ms
| self time by module | ms |
| --- | ---: |
| src/lib/validations/source-priority.ts | 15 |
| npm:@prisma/client | 13.7 |
| (native) | 6.6 |
| node:buffer | 6.6 |
| npm:next | 6 |
| npm:pg | 4.5 |
| src/lib/personal-records/pr-detection-worker.ts | 4.1 |
| src/lib/tz/format.ts | 3.1 |
| node:internal/process/task_queues | 1.5 |
| node:internal/async_hooks | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 25.3 |
| src/lib/analytics/source-priority.ts | 18.1 |
| src/lib/validations/source-priority.ts | 16.5 |
| src/lib/tz/format.ts | 3.1 |
| src/lib/measurements/consolidation-tz.ts | 3.1 |
| src/lib/measurements/consolidation-base.ts | 3.1 |
### at 56923 ms, 52 ms
| self time by module | ms |
| --- | ---: |
| (native) | 20 |
| npm:@prisma/client | 10.1 |
| node:buffer | 3.7 |
| npm:pg | 3 |
| src/lib/tz/format.ts | 2.6 |
| npm:pg-protocol | 2.6 |
| src/lib/analytics/source-priority.ts | 2.6 |
| src/lib/personal-records/pr-detection-worker.ts | 1.5 |
| src/lib/tz/zone-offset.ts | 1.5 |
| npm:pg-types | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 9.3 |
| src/lib/analytics/source-priority.ts | 5.3 |
| src/lib/tz/format.ts | 4.1 |
| src/lib/measurements/consolidation-tz.ts | 4.1 |
| src/lib/measurements/consolidation-base.ts | 2.6 |
| src/lib/tz/zone-offset.ts | 1.5 |
| src/lib/validations/source-priority.ts | 1.1 |
### at 59508 ms, 56 ms
| self time by module | ms |
| --- | ---: |
| npm:@prisma/client | 15.7 |
| src/lib/validations/source-priority.ts | 9.7 |
| node:buffer | 7 |
| (native) | 6.1 |
| npm:pg-protocol | 4.5 |
| npm:next | 4.1 |
| src/lib/tz/format.ts | 3 |
| src/lib/analytics/source-priority.ts | 3 |
| node:internal/async_hooks | 1.5 |
| src/lib/measurements/consolidation-base.ts | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 21.7 |
| src/lib/analytics/source-priority.ts | 15.8 |
| src/lib/validations/source-priority.ts | 9.7 |
| src/lib/tz/format.ts | 5.9 |
| src/lib/measurements/consolidation-tz.ts | 5.9 |
| src/lib/measurements/consolidation-base.ts | 5.9 |
| src/lib/tz/zone-offset.ts | 2.9 |
### at 61315 ms, 62 ms
| self time by module | ms |
| --- | ---: |
| src/lib/validations/source-priority.ts | 20.1 |
| npm:@prisma/client | 14.1 |
| (native) | 8.2 |
| npm:pg | 4.5 |
| node:buffer | 3.1 |
| src/lib/personal-records/pr-detection-worker.ts | 3 |
| src/lib/measurements/consolidation-base.ts | 3 |
| npm:pg-protocol | 1.5 |
| npm:next | 1.5 |
| src/lib/analytics/source-priority.ts | 1.4 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 30.3 |
| src/lib/analytics/source-priority.ts | 22.8 |
| src/lib/validations/source-priority.ts | 21.4 |
| src/lib/measurements/consolidation-base.ts | 4.5 |
| src/lib/tz/zone-offset.ts | 1.5 |
| src/lib/tz/format.ts | 1.5 |
| src/lib/measurements/consolidation-tz.ts | 1.5 |
### at 72986 ms, 57 ms
| self time by module | ms |
| --- | ---: |
| src/lib/validations/source-priority.ts | 19.1 |
| npm:@prisma/client | 10.2 |
| (native) | 6.6 |
| npm:pg-protocol | 5.5 |
| npm:next | 3 |
| src/lib/analytics/source-priority.ts | 3 |
| npm:pg | 2.5 |
| src/lib/personal-records/pr-detection-worker.ts | 1.5 |
| node:internal/async_local_storage/async_hooks | 1.5 |
| src/lib/tz/format.ts | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 29.6 |
| src/lib/analytics/source-priority.ts | 23.5 |
| src/lib/validations/source-priority.ts | 19.1 |
| src/lib/measurements/consolidation-base.ts | 4.6 |
| src/lib/tz/format.ts | 4.5 |
| src/lib/measurements/consolidation-tz.ts | 4.5 |
| src/lib/tz/zone-offset.ts | 3 |
### at 73523 ms, 51 ms
| self time by module | ms |
| --- | ---: |
| src/lib/validations/source-priority.ts | 12 |
| npm:next | 8.9 |
| npm:@prisma/client | 6 |
| (native) | 4.5 |
| src/lib/analytics/source-priority.ts | 4.2 |
| node:buffer | 4 |
| npm:pg | 2.1 |
| npm:pg-protocol | 1.5 |
| src/lib/personal-records/pr-detection-worker.ts | 1.5 |
| src/lib/tz/zone-offset.ts | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 27.8 |
| src/lib/analytics/source-priority.ts | 17.7 |
| src/lib/validations/source-priority.ts | 13.5 |
| src/lib/measurements/consolidation-base.ts | 8.6 |
| src/lib/tz/format.ts | 7.1 |
| src/lib/measurements/consolidation-tz.ts | 7.1 |
| src/lib/tz/zone-offset.ts | 6 |
### at 75393 ms, 100 ms
| self time by module | ms |
| --- | ---: |
| (native) | 32.6 |
| npm:@prisma/client | 17.2 |
| src/lib/validations/source-priority.ts | 14.6 |
| npm:next | 7.5 |
| src/lib/personal-records/pr-detection-worker.ts | 6.1 |
| src/lib/tz/zone-offset.ts | 5.6 |
| npm:pg-protocol | 4.1 |
| npm:pg | 2.5 |
| src/lib/tz/format.ts | 2.3 |
| node:internal/async_local_storage/async_hooks | 1.5 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 34.6 |
| src/lib/analytics/source-priority.ts | 24.3 |
| src/lib/validations/source-priority.ts | 16.1 |
| src/lib/tz/format.ts | 10.9 |
| src/lib/measurements/consolidation-tz.ts | 10.9 |
| src/lib/tz/zone-offset.ts | 8.6 |
| src/lib/measurements/consolidation-base.ts | 5.7 |
### at 78085 ms, 54 ms
| self time by module | ms |
| --- | ---: |
| src/lib/tz/zone-offset.ts | 26.6 |
| src/lib/validations/source-priority.ts | 13.5 |
| npm:@prisma/client | 4.2 |
| (native) | 4.1 |
| node:internal/async_local_storage/async_hooks | 1.5 |
| src/lib/tz/format.ts | 1.5 |
| src/lib/tz/intl-cache.ts | 1.5 |
| npm:pg | 1.1 |
| inclusive, application modules | ms |
| --- | ---: |
| src/lib/personal-records/pr-detection-worker.ts | 44.7 |
| src/lib/tz/format.ts | 29.6 |
| src/lib/measurements/consolidation-tz.ts | 29.6 |
| src/lib/measurements/consolidation-base.ts | 29.6 |
| src/lib/tz/zone-offset.ts | 28.1 |
| src/lib/analytics/source-priority.ts | 15 |
| src/lib/validations/source-priority.ts | 13.5 |
| src/lib/tz/intl-cache.ts | 1.5 |
## Self time by module until the worker is ready
| module | ms |
| --- | ---: |
| (native) | 853 |
| npm:@prisma/client | 295.9 |
| node:internal/modules/cjs/loader | 248.7 |
| src/lib/validations/source-priority.ts | 210.3 |
| npm:next | 188.4 |
| turbopack:///[turbopack]/nodejs/runtime/build-base.ts | 121.5 |
| src/lib/tz/zone-offset.ts | 83.2 |
| wasm://wasm/00d1cb12 | 81.4 |
| npm:pg | 78.5 |
| node:buffer | 59.1 |
| src/lib/tz/format.ts | 55 |
| npm:zod | 50.7 |
| src/lib/personal-records/pr-detection-worker.ts | 48 |
| npm:pg-protocol | 37 |
| node:internal/bootstrap/realm | 32 |
| src/lib/analytics/source-priority.ts | 31.7 |
| turbopack:///[turbopack]/shared/runtime/async-module.ts | 27.7 |
| node:internal/modules/esm/utils | 26 |
| npm:luxon | 22.1 |
| node:internal/async_hooks | 21.7 |
| node:internal/async_local_storage/async_hooks | 21.2 |
| node:fs | 18.8 |
| npm:pg-boss | 18.3 |
| npm:pg-pool | 18.1 |
| npm:yaml | 15 |
## Heap snapshot after 300 s idle (live heap after a full GC)
159.5 MB in 1302659 nodes; module source strings over 50 KB: 39.8 MB.
- parsed locale catalogs: 2 objects, 1.6 MB retained
| node type | MB |
| --- | ---: |
| string | 67.5 |
| array | 26.6 |
| code | 19.2 |
| object | 15.9 |
| hidden | 9.2 |
| native | 8 |
| object shape | 5.9 |
| closure | 5.2 |
| concatenated string | 1.3 |
| number | 0.5 |
| sliced string | 0.2 |
| regexp | 0.2 |
| synthetic | 0 |
| symbol | 0 |
| bigint | 0 |
| constructor | MB | count |
| --- | ---: | ---: |
| array:(object elements) | 20.8 | 25651 |
| object:Object | 11.4 | 293893 |
| native:system / JSArrayBufferData | 7.5 | 170 |
| array:(object properties) | 3.3 | 6517 |
| array: | 2.5 | 10169 |
| closure: | 1.6 | 29121 |
| object:system / Context | 1.6 | 28886 |
| closure:native_bind | 1 | 20804 |
| object:Array | 0.6 | 20938 |
| object:Date1 | 0.5 | 5332 |
| object:a | 0.4 | 4438 |
| native:Node / histogram | 0.4 | 1 |
| object:d | 0.3 | 4425 |
| closure:get | 0.3 | 4732 |
| object:Set | 0.2 | 5670 |
| object:Module | 0.2 | 1963 |
| closure:set | 0.2 | 3428 |
| closure:n | 0.1 | 1572 |
| closure:i | 0.1 | 1578 |
| object:Promise | 0.1 | 1341 |
| largest retained subtrees | MB | retaining path |
| --- | ---: | --- |
| object:yr | 34.6 | [1] > [10] > 22 > extension > global > prisma > [1] > _engine |
| object:system / Context | 7.4 | Node / PrincipalRealm > base_object_list > Node / BaseObjectList > [25] > Node / ModuleWrap > native_to_javascript > ModuleWrap > 2 > [4] > context |
| object:Promise | 5.9 | Object > executor > e > #r > gr > transactions > Map > table > > 6 > closing |
| object:Module | 5.6 | [1] > [10] > 99 > process > getBuiltinModule > getBuiltinModule > context > system / Context > $Module > Module > _cache > |
| code:.next/server/chu | 5.6 | Module > _cache > Object > .next/server/chunks/_1kwfnjg._.js > Module > exports > Array > [1] > > shared > script |
| code:.next/server/chu | 5.6 | global > prisma > [1] > t > _engineConfig > Object > compilerWasm > Object > getRuntime > getRuntime > shared > script |
| object:Generator | 4.4 | [6] > principal_realm > Node / PrincipalRealm > base_object_list > Node / BaseObjectList > [26] > Node / ModuleWrap > native_to_javascript > ModuleWrap > 2 > [4 |
| string:AGFzbQEAAAABtgRLYAN/f38Bf2ACf38Bf2ACf38AYAF/AGADf39/AGAEf39/ | 4.4 | [1] > [21] > 60025 |
| object:Object | 3.4 | system / Context > $Module > Module > _cache > Object > .next/server/chunks/[turbopack]_runtime.js > Module > export |
| object:global | 2.6 | [1] > [10] > 22 > extension |
| largest strings | MB |
| --- | ---: |
| module.exports=[234494,A=>{"use strict";var e,C,g,I,Q=Object.defineProperty,B={},s={$:()=> | 5.6 |
| module.exports=[17856,A=>{"use strict";var e,C,g,I,Q=Object.defineProperty,B={},s={$:()=>i | 5.6 |
| module.exports=[17856,A=>{"use strict";var e,C,g,I,Q=Object.defineProperty,B={},s={$:()=>i | 5.6 |
| const wasm = "AGFzbQEAAAABtgRLYAN/f38Bf2ACf38Bf2ACf38AYAF/AGADf39/AGAEf39/fwBgBX9/f39/AGAB | 4.4 |
| AGFzbQEAAAABtgRLYAN/f38Bf2ACf38Bf2ACf38AYAF/AGADf39/AGAEf39/fwBgBX9/f39/AGABfwF/YAZ/f39/f3 | 4.4 |
| lliADOAUngIEAACgKwAgBgAAoSsAIAcAAKErACAIAACiKwAgCQAAoysAIAoAAKQrACALAAClKwAgDAAApisAIA0AAK | 1.9 |
| (()=>{var e,t,r={"./dist/build/webpack/alias/react-dom-server.js"(e,t,r){"use strict";var | 1.3 |
| module.exports=[842865,(e,t,r)=>{let i=e.r(522734);t.exports=function(e){return e?/-----BE | 1.2 |
| module.exports=[842865,(e,t,r)=>{let i=e.r(522734);t.exports=function(e){return e?/-----BE | 1.2 |
| module.exports=[799092,(e,t,n)=>{"use strict";Object.defineProperty(n,"__esModule",{value: | 1.1 |
| // v1.4.34 web-freeze. Schema is locked additive-only until iOS launch // + v1.5.0 marker. | 1.1 |
| module.exports=[971743,(A,e,t)=>{"use strict";let r=A.r(57328),{addAbortListener:s}=A.r(68 | 1.1 |
| module.exports=[835717,(A,e,t)=>{"use strict";let r=A.r(57328),{addAbortListener:s}=A.r(68 | 1 |
| module.exports=[767189,e=>e.a(async(t,a)=>{try{var n=e.i(64105),r=e.i(563616),i=t([n]);[n] | 0.8 |
| module.exports=[594108,806176,674750,98746,t=>{"use strict";var i;let r;function n(t){retu | 0.7 |
-22
View File
@@ -1,22 +0,0 @@
# v1.45.0: request fan-out
Same runs as `v1.45.0-read-path.md`.
| request | statements before | statements after | p50 ms before / after |
| --- | ---: | ---: | ---: |
| /api/auth/me | 19 | 14 | 9 / 8 |
| day view, cold | 49 | 48 | 77 / 68 |
- `/api/auth/me` read the AppSettings singleton six times (MFA policy,
Assistant switches, module availability, provider presence, AI usage
bounds, reasoning controls); one memoised read per request now serves all
six (`src/lib/settings/operator-row.ts`). On the small budget fixture it
went from 18 to 13 statements. The remaining reads are the session, the
grant, cycle profile, onboarding, consent, coach usage and five user reads
with different column sets.
- The day view's record sections run six at a time instead of about
twenty-five at once, so one day never holds more than a third of the pool.
The statement count is the same; what changes is the peak of connections.
- Keyset pagination for `/api/measurements` was not done: a cursor needs a
new request parameter and a response field, a contract change for the
native client.
-254
View File
@@ -1,254 +0,0 @@
{
"meta": {
"label": "v1.45.0-final",
"commit": "a57fa8335",
"date": "2026-10-22T06:52:09.539Z",
"node": "v22.23.2",
"postgres": "16.15",
"cpus": 14,
"loadAverage": [
6.8,
8.9,
14.5
],
"measurements": 1265561,
"iterations": 20,
"warmup": 3,
"heapMb": 792,
"idleStatementsPerSecond": 0,
"batch5k": {
"totalMs": 4448,
"totalStatements": 504
}
},
"results": [
{
"name": "/api/auth/me",
"mode": "cold",
"request": "GET /api/auth/me",
"n": 20,
"p50Ms": 8.3,
"p95Ms": 27.2,
"maxMs": 221,
"statementsMedian": 14,
"statementsMax": 14,
"failures": 0
},
{
"name": "/api/auth/me",
"mode": "warm",
"request": "GET /api/auth/me",
"n": 20,
"p50Ms": 7.9,
"p95Ms": 10.1,
"maxMs": 17.1,
"statementsMedian": 14,
"statementsMax": 17,
"failures": 0
},
{
"name": "dashboard summary",
"mode": "cold",
"request": "GET /api/dashboard/summary",
"n": 20,
"p50Ms": 86.6,
"p95Ms": 100.8,
"maxMs": 126.8,
"statementsMedian": 30,
"statementsMax": 31,
"failures": 0
},
{
"name": "dashboard summary",
"mode": "warm",
"request": "GET /api/dashboard/summary",
"n": 20,
"p50Ms": 9.2,
"p95Ms": 17.1,
"maxMs": 18.4,
"statementsMedian": 6,
"statementsMax": 6,
"failures": 0
},
{
"name": "dashboard snapshot",
"mode": "cold",
"request": "GET /api/dashboard/snapshot",
"n": 20,
"p50Ms": 545.3,
"p95Ms": 592.5,
"maxMs": 606.3,
"statementsMedian": 153,
"statementsMax": 156,
"failures": 0
},
{
"name": "dashboard snapshot",
"mode": "warm",
"request": "GET /api/dashboard/snapshot",
"n": 20,
"p50Ms": 8.1,
"p95Ms": 17.9,
"maxMs": 21.9,
"statementsMedian": 10,
"statementsMax": 10,
"failures": 0
},
{
"name": "series pulse 30 d",
"mode": "cold",
"request": "GET /api/measurements/series?kind=pulse&days=30",
"n": 20,
"p50Ms": 18.7,
"p95Ms": 27.2,
"maxMs": 36.1,
"statementsMedian": 8,
"statementsMax": 8,
"failures": 0
},
{
"name": "series pulse 30 d",
"mode": "warm",
"request": "GET /api/measurements/series?kind=pulse&days=30",
"n": 20,
"p50Ms": 15.9,
"p95Ms": 21.8,
"maxMs": 26,
"statementsMedian": 8,
"statementsMax": 8,
"failures": 0
},
{
"name": "series pulse 365 d",
"mode": "cold",
"request": "GET /api/measurements/series?kind=pulse&days=365",
"n": 20,
"p50Ms": 40.7,
"p95Ms": 55.6,
"maxMs": 56.2,
"statementsMedian": 7,
"statementsMax": 8,
"failures": 0
},
{
"name": "series pulse 365 d",
"mode": "warm",
"request": "GET /api/measurements/series?kind=pulse&days=365",
"n": 20,
"p50Ms": 38.3,
"p95Ms": 59.6,
"maxMs": 88.6,
"statementsMedian": 7,
"statementsMax": 7,
"failures": 0
},
{
"name": "series pulse 3650 d",
"mode": "cold",
"request": "GET /api/measurements/series?kind=pulse&days=3650",
"n": 20,
"p50Ms": 334.9,
"p95Ms": 348.5,
"maxMs": 351.2,
"statementsMedian": 7,
"statementsMax": 7,
"failures": 0
},
{
"name": "series pulse 3650 d",
"mode": "warm",
"request": "GET /api/measurements/series?kind=pulse&days=3650",
"n": 20,
"p50Ms": 328.1,
"p95Ms": 346,
"maxMs": 348.9,
"statementsMedian": 7,
"statementsMax": 8,
"failures": 0
},
{
"name": "day view",
"mode": "cold",
"request": "GET /api/day/2026-10-21",
"n": 20,
"p50Ms": 68.4,
"p95Ms": 102.6,
"maxMs": 104.7,
"statementsMedian": 48,
"statementsMax": 49,
"failures": 0
},
{
"name": "day view",
"mode": "warm",
"request": "GET /api/day/2026-10-21",
"n": 20,
"p50Ms": 46.4,
"p95Ms": 66.1,
"maxMs": 72.6,
"statementsMedian": 47,
"statementsMax": 47,
"failures": 0
},
{
"name": "insights health status",
"mode": "cold",
"request": "GET /api/insights/health-status",
"n": 20,
"p50Ms": 156,
"p95Ms": 190,
"maxMs": 197.7,
"statementsMedian": 67,
"statementsMax": 67,
"failures": 0
},
{
"name": "insights health status",
"mode": "warm",
"request": "GET /api/insights/health-status",
"n": 20,
"p50Ms": 173.6,
"p95Ms": 1163.4,
"maxMs": 1419.4,
"statementsMedian": 67,
"statementsMax": 67,
"failures": 0
},
{
"name": "insights correlations",
"mode": "cold",
"request": "GET /api/insights/correlations",
"n": 20,
"p50Ms": 106.1,
"p95Ms": 229.1,
"maxMs": 383.3,
"statementsMedian": 48,
"statementsMax": 49,
"failures": 0
},
{
"name": "insights correlations",
"mode": "warm",
"request": "GET /api/insights/correlations",
"n": 20,
"p50Ms": 18.7,
"p95Ms": 626.6,
"maxMs": 1136.5,
"statementsMedian": 7,
"statementsMax": 7,
"failures": 0
},
{
"name": "batch ingest 5k (per 500)",
"mode": "write",
"request": "POST /api/measurements/batch ×10",
"n": 10,
"p50Ms": 185.7,
"p95Ms": 1269.2,
"maxMs": 1269.2,
"statementsMedian": 50,
"statementsMax": 53,
"failures": 0
}
]
}
-25
View File
@@ -1,25 +0,0 @@
# Benchmark v1.45.0-final
Commit a57fa8335 with the working tree of the final commits, 2026-10-22T06:52:09.539Z. 1265561 measurement rows on the bench account, 20 measured requests per row after 3 warm-up requests, one at a time. Server: production build, web process, heap ceiling 792 MB. Postgres 16.15, 14 cores, load average 6.8,8.9,14.5 at the end. Idle background: 0 statements/s.
| Request | Mode | n | p50 ms | p95 ms | max ms | statements (median) | statements (max) |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: |
| /api/auth/me | cold | 20 | 8.3 | 27.2 | 221 | 14 | 14 |
| /api/auth/me | warm | 20 | 7.9 | 10.1 | 17.1 | 14 | 17 |
| dashboard summary | cold | 20 | 86.6 | 100.8 | 126.8 | 30 | 31 |
| dashboard summary | warm | 20 | 9.2 | 17.1 | 18.4 | 6 | 6 |
| dashboard snapshot | cold | 20 | 545.3 | 592.5 | 606.3 | 153 | 156 |
| dashboard snapshot | warm | 20 | 8.1 | 17.9 | 21.9 | 10 | 10 |
| series pulse 30 d | cold | 20 | 18.7 | 27.2 | 36.1 | 8 | 8 |
| series pulse 30 d | warm | 20 | 15.9 | 21.8 | 26 | 8 | 8 |
| series pulse 365 d | cold | 20 | 40.7 | 55.6 | 56.2 | 7 | 8 |
| series pulse 365 d | warm | 20 | 38.3 | 59.6 | 88.6 | 7 | 7 |
| series pulse 3650 d | cold | 20 | 334.9 | 348.5 | 351.2 | 7 | 7 |
| series pulse 3650 d | warm | 20 | 328.1 | 346 | 348.9 | 7 | 8 |
| day view | cold | 20 | 68.4 | 102.6 | 104.7 | 48 | 49 |
| day view | warm | 20 | 46.4 | 66.1 | 72.6 | 47 | 47 |
| insights health status | cold | 20 | 156 | 190 | 197.7 | 67 | 67 |
| insights health status | warm | 20 | 173.6 | 1163.4 | 1419.4 | 67 | 67 |
| insights correlations | cold | 20 | 106.1 | 229.1 | 383.3 | 48 | 49 |
| insights correlations | warm | 20 | 18.7 | 626.6 | 1136.5 | 7 | 7 |
| batch ingest 5k (per 500) | write | 10 | 185.7 | 1269.2 | 1269.2 | 50 | 53 |
@@ -1,45 +0,0 @@
# v1.45.0: read path
Request benchmark on the seeded account (1,265,561 rows), production build,
web process, heap ceiling 792 MB, 20 requests per row, one at a time.
`v1.45.0-before` is the v1.44 runtime (1915f9152), `v1.45.0-final` this
branch; both on the same machine within the hour, load average 7 to 30
(other work on the host), so latency compares within a factor of noise and
statements exactly. Cold means every request follows a one-row manual sync.
| request | before p50 / p95 ms | after p50 / p95 ms | statements before / after |
| --- | ---: | ---: | ---: |
| dashboard snapshot, cold | 1482 / 1526 | 545 / 593 | 158 / 153 |
| dashboard summary, cold | 170 / 221 | 87 / 101 | 31 / 30 |
| series pulse 3650 d, cold | 1627 / 1665 | 335 / 349 | 8 / 7 |
| series pulse 3650 d, warm | 2091 / 2435 | 328 / 346 | 8 / 7 |
| series pulse 365 d, cold | 184 / 193 | 41 / 56 | 8 / 7 |
| series pulse 30 d, cold | 24 / 31 | 19 / 27 | 8 / 8 |
| insights health status, cold | 245 / 401 | 156 / 190 | 68 / 67 |
What moved them:
- **JIT off for app sessions.** Postgres compiled every fold whose estimated
cost passed `jit_above_cost`; on the ten-year pulse pick that was 100 to
140 ms of a 220 ms statement (`EXPLAIN ANALYZE`: 395 ms with JIT, 220 ms
without).
- **The canonical-source pick groups first.** `DISTINCT ON` now sorts the
distinct `(type, day, source)` triples instead of every raw reading (the
ten-year pulse pick sorted 260,000 rows and spilled to disk); 220 ms to
175 ms on its own. Parity: `tests/integration/canonical-source-pick-parity.test.ts`
runs the old statement beside the new one over five reader shapes and two
ladders on a fixture with overlapping and off-ladder sources, tombstones,
empty days and readings around midnight; identical rows.
- **The dense series reads its rows once.** Buckets and strip figures come
from one statement over a materialised window instead of two statements
that each picked the canonical source and scanned the readings. Parity:
`tests/integration/dense-series-read-parity.test.ts`, the two old
statements as reference, pulse (two ranked sources), glucose and oxygen
saturation, day and hour grains, UTC, Europe/Berlin, Asia/Kolkata and
America/New_York; identical buckets and figures (relative 1e-9).
- **Closed blocks survive a sync.** The slice's pre-fold remainder (every
reading older than five years, the snapshot's largest statement at 357 ms)
and the day view's past history blocks are cached under a key that names
the instant their readings end before; a sync of newer readings no longer
drops them (`src/lib/cache/closed-block.ts`). The values are the same
statement's; only how long they are kept changed.
@@ -1,28 +0,0 @@
# v1.45.0: workout duplicate window
A correctness change, not a speed one; the request benchmark does not read
workouts, so there is no latency row for it.
Before: two copies of one session were collapsed only when both starts fell
in the same fixed five-minute clock slot (`floor(start / 5 min)`). A pair 30 s
apart that straddled a slot boundary stayed two workouts in the list, the
batch write, the calendar, strain and the Coach.
After: per user and sport, sorted by start, a workout joins the open cluster
while it starts less than five minutes after the cluster's first start.
Proof (`src/lib/measurements/__tests__/pick-canonical-workout-rows.property.test.ts`,
against the previous picker kept as `pick-canonical-workout-rows.legacy.ts`):
| property | inputs |
| --- | --- |
| same rows as the fixed slots wherever no pair within five minutes straddles a slot boundary, three ladders | 4,000 generated inputs, over 1,000 comparable |
| same strain impulses as before on those inputs | 2,000 generated inputs, over 500 comparable |
| two sources' copies collapse at any offset under five minutes (the old picker missed a share) | 3,000 random offsets |
| five minutes or more apart never collapse | 2,000 |
| a uniform shift of every start keeps the picked set | 1,500 |
| a row of workouts four minutes apart does not chain | fixed case |
One existing case changed its expectation: three runs at 08:04, 08:08 and
08:12 used to stay three because they sat in three slots; 08:08 is now the
08:04 run from a lower-ranked source (four minutes apart), and 08:12 stays.
@@ -1,26 +0,0 @@
# v1.45.0: write path
Same runs as `v1.45.0-read-path.md`.
| request | before p50 ms | after p50 ms | statements before / after |
| --- | ---: | ---: | ---: |
| batch ingest, 500 fresh rows per request | 166 | 186 | 53 / 50 |
Fresh rows were already set-based (v1.44); the benchmark's ingest is all
fresh rows, so it shows no gain, as expected. The changes are for re-posts:
- **Unchanged `stats:` re-posts** write nothing and start nothing. One read
over the batch's `stats:` ids replaces a reconciler transaction (about ten
round trips) per row, and an all-unchanged batch no longer refolds, enqueues
rollups or PR detection, or marks caches stale. The per-entry status stays
`updated` and the summary's `updated` count is unchanged.
`tests/integration/routes/measurements-batch-unchanged-stats.test.ts`: four
unchanged re-posts take at most 12 statements in total (before: about 40)
with zero rollup, invalidation and PR calls; a changed value, a changed
device or a tombstoned row still goes through the reconciler.
- **Apple Health re-import** skips the UPDATE of a row stored with exactly the
values it would write; one read per chunk instead of one UPDATE per row.
`tests/integration/apple-health-reimport-unchanged.test.ts`: a re-import of
20 stored rows reports the same per-type counts and sends no UPDATE.
- **Narrower invalidation.** The batch route tells the cache how far back it
wrote (`touchedFrom`), so closed blocks of older readings stay.