From 37d36591c77403f67c61fa2e34b448303c06b6c0 Mon Sep 17 00:00:00 2001 From: lismana Date: Mon, 26 Oct 2026 21:36:34 -0400 Subject: [PATCH] Result cache: size the process-memory LRU with RESULT_CACHE_MB Off Vercel, 'use cache: remote' falls back to Next's in-memory LRU, sized by cacheMaxMemorySize (50 MB by default). A large oncoprint contract is ~2.5 MB packed, so the default holds only a handful. next.config.mjs now takes the size from RESULT_CACHE_MB, defaulting to 50; `next start` reads it at server start, so a deployment can resize the cache without a rebuild. Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 3 ++- docs/ENVIRONMENT.md | 1 + next.config.mjs | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index fb2754c6..1115db95 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -162,7 +162,8 @@ changing first. The parts, and the one place each rule lives: - **`RESULT_CACHE=off` turns it off.** `throughCache` then runs the direct call on every request, so a server answers everything cold — for measuring what a first reader waits for. Without a cache handler configured (anywhere but Vercel), the cache is the Node process's own - 50 MB LRU (`cacheMaxMemorySize`): lost on restart, and not shared between replicas. + LRU (`cacheMaxMemorySize`, 50 MB unless `RESULT_CACHE_MB` says otherwise): lost on restart, + and not shared between replicas. - **Arguments are the key.** A cached function takes only serializable arguments and computes everything else itself; a function passed in cannot be called. Anything that changes the answer must be an argument. diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index 1ee5ccc9..3d93759a 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -131,6 +131,7 @@ see the security notes below. | var | default | meaning | |---|---|---| | `RESULT_CACHE` | on | `off`: answer every request directly, bypassing the result cache, to measure what a first reader waits for | +| `RESULT_CACHE_MB` | `50` | the result cache's size in MB where it is process memory (anywhere but Vercel); read at server start | | `CLICKHOUSE_MAX_INFLIGHT` | `8` | ClickHouse queries in flight at once per process; the rest queue (`docs/PERFORMANCE.md`) | | `EXPLORE_COHORT_EXTERNAL_LIMIT` | `50000` | the most patient ids Explore ships to ClickHouse for one draft cohort | | `ONCOPRINT_CLUSTER_LIMIT` | `4000` | the most columns an oncoprint clusters (`cluster:` sort) | diff --git a/next.config.mjs b/next.config.mjs index 68d7322e..1291909a 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -27,6 +27,9 @@ const nextConfig = (phase) => ({ distDir: process.env.NEXT_DIST_DIR || ".next", // `'use cache: remote'` (lib/next-cache.ts) needs Cache Components cacheComponents: true, + // Off Vercel that cache is this process-memory LRU; `next start` reads it at startup, so a + // deployment sizes it without a rebuild + cacheMaxMemorySize: (Number(process.env.RESULT_CACHE_MB) || 50) * 1024 * 1024, // hosts besides localhost that may load `next dev`'s scripts and HMR socket (e.g. a tailnet // proxy in front of a dev server); comma-separated, dev only allowedDevOrigins: (process.env.ALLOWED_DEV_ORIGINS || "").split(",").map((h) => h.trim()).filter(Boolean),