{"id":"6a220f70b10bce5edbd0831f","title":"2026 06 05 Issue 285","path":"how-to/committee/release-notes/2026-06-05-issue-285","contentMarkdown":"# 05-Jun-2026 — reduce request memory pressure with lean reads, tile timeout and capped queries [ref #285](https://github.com/nbarrett/ngx-ramblers/issues/285)\n\n## [build 668](https://github.com/nbarrett/ngx-ramblers/actions/runs/26985886613) — [commit c8bedc9](https://github.com/nbarrett/ngx-ramblers/commit/c8bedc97ebe386f6337502c557cfa2608e2269a2)\n\n_____\n\n## What's New\n\nTwo rounds of request-memory work, combined. Server read queries now return plain objects instead of full Mongoose documents, the OS Maps tile proxy gives up on a hung upstream rather than holding the request open, and unbounded \"all\" queries are capped so a large dataset cannot exhaust the machine's memory.\n\nRelated issue: [#285 - perf(walks): unbounded event queries cause request-memory OOM on large area-scoped sites](https://github.com/nbarrett/ngx-ramblers/issues/285)\n\n### How it behaves\n\n- Read queries (findOne, findById, find, paginated find) use `.lean()`, returning plain objects and skipping Mongoose document hydration, which is the main per-request memory cost on large result sets.\n- The OS Maps tile proxy now times out an upstream request after 10 seconds and returns 504, so a stalled tile fetch cannot pile up and hold memory.\n- The non-paginated `all` query branch caps at 1000 documents when no explicit limit is supplied, logging a warning that names the model and criteria. Callers passing an explicit limit are unaffected.\n- The walks map view passes an explicit limit so map loading is intentionally bounded.\n\n### Why it matters\n\nOn area-scoped sites (for example Kent, with 4205 events) an unbounded \"all events\" query returned every matching document as full Mongoose objects, driving Firecracker memory toward the 512MB ceiling; a live test returned HTTP 503 after 35 seconds. Group sites hold a fraction of the data so never hit this. It matters for the Ramblers HQ rollout, where many large area-scoped sites are expected.\n\n### Technical changes\n\n- crud-controller: `.lean()` on findOne, findOneDocument, both find branches and findById; new UNPAGINATED_RESULT_CAP (1000) applied to the non-paginated branch when no explicit limit, with a warning log on truncation.\n- os-maps-proxy: 10 second upstream request timeout returning 504 on a stalled tile fetch.\n- events-full map view and map.model: explicit MAP_VIEW_MAX_EVENTS (1000) limit on the map query.","contentHtml":"<h1>05-Jun-2026 — reduce request memory pressure with lean reads, tile timeout and capped queries <a href=\"https://github.com/nbarrett/ngx-ramblers/issues/285\">ref #285</a></h1>\n<h2><a href=\"https://github.com/nbarrett/ngx-ramblers/actions/runs/26985886613\">build 668</a> — <a href=\"https://github.com/nbarrett/ngx-ramblers/commit/c8bedc97ebe386f6337502c557cfa2608e2269a2\">commit c8bedc9</a></h2>\n<hr>\n<h2>What&#39;s New</h2>\n<p>Two rounds of request-memory work, combined. Server read queries now return plain objects instead of full Mongoose documents, the OS Maps tile proxy gives up on a hung upstream rather than holding the request open, and unbounded &quot;all&quot; queries are capped so a large dataset cannot exhaust the machine&#39;s memory.</p>\n<p>Related issue: <a href=\"https://github.com/nbarrett/ngx-ramblers/issues/285\">#285 - perf(walks): unbounded event queries cause request-memory OOM on large area-scoped sites</a></p>\n<h3>How it behaves</h3>\n<ul>\n<li>Read queries (findOne, findById, find, paginated find) use <code>.lean()</code>, returning plain objects and skipping Mongoose document hydration, which is the main per-request memory cost on large result sets.</li>\n<li>The OS Maps tile proxy now times out an upstream request after 10 seconds and returns 504, so a stalled tile fetch cannot pile up and hold memory.</li>\n<li>The non-paginated <code>all</code> query branch caps at 1000 documents when no explicit limit is supplied, logging a warning that names the model and criteria. Callers passing an explicit limit are unaffected.</li>\n<li>The walks map view passes an explicit limit so map loading is intentionally bounded.</li>\n</ul>\n<h3>Why it matters</h3>\n<p>On area-scoped sites (for example Kent, with 4205 events) an unbounded &quot;all events&quot; query returned every matching document as full Mongoose objects, driving Firecracker memory toward the 512MB ceiling; a live test returned HTTP 503 after 35 seconds. Group sites hold a fraction of the data so never hit this. It matters for the Ramblers HQ rollout, where many large area-scoped sites are expected.</p>\n<h3>Technical changes</h3>\n<ul>\n<li>crud-controller: <code>.lean()</code> on findOne, findOneDocument, both find branches and findById; new UNPAGINATED_RESULT_CAP (1000) applied to the non-paginated branch when no explicit limit, with a warning log on truncation.</li>\n<li>os-maps-proxy: 10 second upstream request timeout returning 504 on a stalled tile fetch.</li>\n<li>events-full map view and map.model: explicit MAP_VIEW_MAX_EVENTS (1000) limit on the map query.</li>\n</ul>\n"}