Tabs: avoid repeated full Tasks reads during switching storms #1376

Open
opened 2026-10-07 15:02:46 +00:00 by kayg · 0 comments
Owner

Found in the production Tab-switching storm for #1338. Related: #1338 and #1233.

Across the three measured storms, the browser sent 2,973 Task API requests with 4× CPU throttling and 3,297 without throttling. The CPU4 post-storm trace contains 131 GET /api/v1/notes/tasks?limit=100&cursor=0 requests and 14 /api/v1/notes/tasks/views requests in 15.8 seconds. This is the first page of the full Task collection repeating; the trace has no per-request initiator stack, so the trigger needs confirmation.

The source path to audit is TaskIndex.#watch() → TaskIndex.refresh() → TaskIndex.#read() in apps/web/src/lib/tasks/index.svelte.ts (around lines 171–179 and 146–153), then listAllTasks() in apps/web/src/lib/tasks/api.ts (around lines 35–47). #watch() schedules a full read after each Notes change event. listAllTasks() fetches each 100-row page until it has the full collection. With 1,000 fixture Tasks, one refresh reads at least ten pages. The client collection is shared with the Tasks sidebar, so please confirm which change events keep triggering the repeated reads and use bounded deltas or coalescing appropriate for the shared Index.

The profile grouped all requests made while each Tab was selected. Tasks recorded 249/1/4 total/aborted/max-in-flight with CPU4 and 520/1/8 without throttle. The endpoint category recorded 2,973 and 3,297 requests respectively; none were aborted. The server RSS also rose during each condition, but this browser trace does not prove that Task reads caused the server growth.

Trace: artifacts/tabstorm-1338/cpu4-budget-failure-trace.json. Storm CSV and summary are in docs/perf/runs/2026-10-07-1338-tabstorm* on the job branch.

Found in the production Tab-switching storm for #1338. Related: #1338 and #1233. Across the three measured storms, the browser sent 2,973 Task API requests with 4× CPU throttling and 3,297 without throttling. The CPU4 post-storm trace contains 131 `GET /api/v1/notes/tasks?limit=100&cursor=0` requests and 14 `/api/v1/notes/tasks/views` requests in 15.8 seconds. This is the first page of the full Task collection repeating; the trace has no per-request initiator stack, so the trigger needs confirmation. The source path to audit is `TaskIndex.#watch()` → `TaskIndex.refresh()` → `TaskIndex.#read()` in `apps/web/src/lib/tasks/index.svelte.ts` (around lines 171–179 and 146–153), then `listAllTasks()` in `apps/web/src/lib/tasks/api.ts` (around lines 35–47). `#watch()` schedules a full read after each Notes change event. `listAllTasks()` fetches each 100-row page until it has the full collection. With 1,000 fixture Tasks, one refresh reads at least ten pages. The client collection is shared with the Tasks sidebar, so please confirm which change events keep triggering the repeated reads and use bounded deltas or coalescing appropriate for the shared Index. The profile grouped all requests made while each Tab was selected. Tasks recorded 249/1/4 total/aborted/max-in-flight with CPU4 and 520/1/8 without throttle. The endpoint category recorded 2,973 and 3,297 requests respectively; none were aborted. The server RSS also rose during each condition, but this browser trace does not prove that Task reads caused the server growth. Trace: `artifacts/tabstorm-1338/cpu4-budget-failure-trace.json`. Storm CSV and summary are in `docs/perf/runs/2026-10-07-1338-tabstorm*` on the job branch.
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-v0#1376
No description provided.