Repository navigation
Description
What happened
#390 (ja PR 2 of 7 for #388, +11 ja pages) merged as 3bbc710. The post-deploy smoke check then failed twice, on main CI run 40862958838 and on its re-run. The failure card is #391.
/api/searchanswered 503, Cloudflare's HTML error page, after 9–12 s. It failed for zh-Hant, de and fr on the first attempt, and for es, fr and the en nonce control on the re-run.- Every page rendered.
- Both deploys rolled back, so the live site serves the docs(i18n): translate build/ and build/data/ into ja (#388, PR 1 of 7) #389 version.
On the previous run, 40861333382 for #389, all eight locales answered 200 in 3.6–5.3 s each. #392 reverts #390 so that main can deploy again.
Cause, measured
apps/docs/app/api/search/route.ts builds one Orama index per locale on that locale's first search (#301). It keeps each index in a module-level servers map that is never emptied, so one isolate holds as many indexes as locales it has served.
The measurement asked the built route under Node (next build at 3bbc710, then routeModule.userland.GET, --expose-gc), one ?query=permissions per locale in order. Heap is heapUsed after a forced GC.
| after | heap, as on main |
heap, map emptied before each new build |
|---|---|---|
| route loaded | 17.9 MB | 17.9 MB |
| en | 58.6 MB | 58.5 MB |
| zh-Hans | 98.2 MB | 72.5 MB |
| zh-Hant | 137.3 MB | 83.3 MB |
| ja | 174.2 MB | 87.4 MB |
| de | 203.6 MB | 86.1 MB |
| es | 232.4 MB | 86.3 MB |
| fr | 259.9 MB | 85.2 MB |
| ko | 285.9 MB | 86.8 MB |
- Index size. Each locale's index holds 30–40 MB. A Worker isolate has 128 MB, so two or three indexes and the rest of the app already fill it. That is why the 503s hit the second or third locale an isolate served.
- The prototype. One line,
servers.clear()before a new build, keeps a single index. Heap levels off at about 86 MB. - What is left. The remaining growth from 58 to 86 MB is the compiled page modules that
page.data.load()imports for each locale. They stay in the module registry. - Full ja coverage. With every missing ja page faked as a copy of the English, the one-index prototype levels off at about 94 MB.
Ask
Make /api/search fit the Worker with room to spare, now and after #388 brings ja to full coverage (79 more pages) and phase 3 adds further locales.
- Bound the per-isolate index cache. A single entry is the measured minimum. Say what a locale switch then costs (measured 0.5–1.5 s per rebuild), and whether a second entry fits.
- Look at what stays resident besides the index. The question is whether search can index without keeping every page module of every locale loaded. One option is
structuredDatawritten at build time to a per-locale JSON that the route reads, while keeping the/api/searchserver contract that Docs polish from the 2026-10-06 audit: muted-text contrast, the License table on phones, FAQ formatting, search ranking, glossary order, licence/license spelling #301 explains. Measure before and after. - Make the limit testable before deploy. Add a heap check to
check-search-locales.mjs(or a sibling script) after the build. It asks every locale in turn, then fails above a budget that leaves headroom under 128 MB, such as 100 MBheapUsedafter GC. A future content PR should then go red in CI, not after deploy.
Acceptance
- The heap table above, re-measured on the PR, levels off under the budget, both on
mainand with full ja coverage simulated. check-search-localespasses, with every locale's results unchanged and the Docs polish from the 2026-10-06 audit: muted-text contrast, the License table on phones, FAQ formatting, search ranking, glossary order, licence/license spelling #301 ranking still holding.- After it lands, the post-deploy smoke check is green. Then docs(i18n): translate build/automation/ and build/interface/ into ja (#388, PR 2 of 7) #390's pages re-land (revert Revert #390 (ja build/automation and build/interface) so search fits the Worker again #392) and the smoke check stays green.
Activity
objectstack-fleet commentedon Oct 29, 2026
Claim: search memory fix, blocking #388 · 2026-10-29T11:28Z
Session:
session_01QsR2jTaZ2GeyfjANMwstiw(seat thread; the dev is card threadsession_01QsR2jRsjbApbf83iyTDDXm, which also holds #388, identity by branch)Account:
zhuangjianguoBranch:
claude/project-thread-u7eoxi(platform-assigned; restarted frommain)Worktree: the card thread's own
docs.objectos.aicheckoutDomain:
domain:docs(single-lane repository)Seat:
repo:docs.objectos.ai#1File surface:
apps/docs/app/api/search/route.ts;.github/scripts/check-search-locales.mjsor a new sibling heap-check script, plus itsSELF_TESTEDentry intools/ci-scripts/run-self-tests.mjsand its CI step if it is a new script; any build-time step that item 2 needs underapps/docs/(for examplesource.config.tsorscripts/). No content files. If the work goes beyond this surface, stop and explain why in the report.Container & model: S,
mode:thread,model: default tier (TIER_DEFAULT — sister repository, hand-derived: no packages/spec, no protocol-semantic surface),effort: project defaultClause-②: no
Metadata-protocol: none
Responsibility: production regression on the deploy path. #390 tipped search over the Worker memory limit, and #392 reverts it.
Thread-read: none
Premise: confirmed by the seat's heap measurement in the card body (built route at
3bbc710, Node--expose-gc) and by both smoke logs of run 40862958838.Tier: none.
Serial constraints cleared: the lane is serial. #388 pauses after its PR 1 (#389) until this card lands, and it resumes by re-landing #390's pages. #392 (the revert) is the only other PR in flight, and it touches content only.
fix(search): keep one locale index and read search text from build ou…
Merge the landed #390 branch head so the push fast-forwards
objectstack-fleet commentedon Oct 29, 2026
Landing · 2026-10-29T12:28Z ·
session_01QsR2jTaZ2GeyfjANMwstiw· seatrepo:docs.objectos.ai#1#394 merged as
9e51646, and it closed this card. Main CI run 40872624098 is green:buildsuccess, including the newSearch fits the Worker's memorystep. Publish success, the new version is serving, and the smoke check passed, with search answering in all eight locales and no rollback. Next, #388 resumes by re-landing #390's pages. The Worker size limit the dev measured is tracked on #395.docs(i18n): re-land build/automation/ and build/interface/ ja pages (#…