Skip to content

perf(inbox): Settings → Storage counts its sizes on its own, only when shown - #2546

Merged
backnotprop merged 7 commits into
mainfrom
perf/inbox-storage-on-demand
Nov 3, 2026
Merged

backnotprop merged 7 commits into
mainfrom
perf/inbox-storage-on-demand

Conversation

@backnotprop

@backnotprop backnotprop commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

What this changes

Every time the Inbox window read its settings (on load, on opening Settings, after most saves, and in every window after some changes), the server also counted every file in the Inbox to fill one panel: Settings → Storage. That count reads every message file on disk, on the server's only thread, so everything else waited behind it.

Now the settings read leaves the count out. Settings → Storage asks for it on its own, each time it opens, through a new route: GET /api/inbox/settings/storage.

What you see

Only Settings → Storage looks different, and only while the count runs. This is the loading state the owner chose ("A · The calm wait"):

  • The heading and the line under it stay in place. The total is a soft grey bar until the number comes.
  • The card keeps its place and height. No spinner.
  • "Counting what is stored…" shows only if the count takes longer than 0.4 s.
  • The numbers fade in (160 ms). With reduced motion on, they appear without a fade.
  • The numbers are kept for the visit: open Storage a second time and they show at once, then update quietly.

Delete thread and Delete project still update the numbers: their answer already carries the new count, and the window now uses it (one count per delete instead of two).

Numbers (L data set, server only, median of 7)

Before After
Settings read 293 ms 0.94 ms
A list read sent while a Settings read runs 347 ms 52.7 ms
The Storage count on its own (new route) n/a 265 ms

Notes

  • The Inbox runs only on the Bun server, so there is no Pi change. The Pi server has no /api/inbox/settings* route.
  • The settings read now has store_dir, so the Storage line can show the folder before the count arrives.
  • The Server API table in docs/agent-guides/server-and-storage.md and the Storage line in docs/agent-guides/inbox-window.md are updated.
  • A page left open from before the update still gets store in its settings read, so it keeps working until it reloads; the new page asks with ?store=0 and never pays for the count there.

Tests

  • packages/server/inbox.test.ts: the settings read does not count the files (no diskUsage() call, no store), and the new route returns the same numbers the store counts (the exact bytes on disk). It fails on main: the settings read counts once.
  • packages/inbox/settingsSections.test.tsx (DOM): Settings does not ask for the count; Storage asks when it opens; before 0.4 s there is a bar and no "Counting…", after 0.4 s "Counting what is stored…" shows; then the numbers match the server's; a second visit shows them at once. It fails on main: Storage never asks.
  • packages/server/inbox-project-combine.test.ts reads the per-folder sizes from the new route.

backnotprop and others added 2 commits November 2, 2026 18:49
… shown

GET /api/inbox/settings no longer walks every file in the store; the new
GET /api/inbox/settings/storage does, and only the Storage panel asks for
it, each time it opens. While the first count runs, the panel shows the
calm wait the owner chose: the card holds its place, the total is a soft
grey bar, "Counting what is stored…" after 0.4 s, the numbers fade in.

Co-Authored-By: Claude <noreply@anthropic.com>
…alled storage read times out, Try again shows the wait

- P1-1: the window asks GET /api/inbox/settings?store=0; a read without the
  marker (a page older than the storage route) still gets store, so it no
  longer blanks the window after an update.
- P2-1: the folder line falls back to an older Inbox's settings.store.dir.
- P3-1: the storage read gives up after 20 s (getWithin).
- P3-2: a read starting clears the error; no aria-busy around the alert.
- P3-3: the slow words reset on leaving Storage, not on the next open.
- P3-4: the DOM test times the words with an observer from before the click.
- P3-5: the failure state and the marker in the docs.

Co-Authored-By: Claude <noreply@anthropic.com>
@backnotprop backnotprop added the ci:full Run the heavy CI tier on this PR (added by the merge script) label Nov 3, 2026
# Conflicts:
#	packages/server/inbox.test.ts
…s ?store=0

#2546 makes the window read GET /api/inbox/settings?store=0. Four DOM tests
compared the fetched URL to the bare '/api/inbox/settings', so:

- palettePicker: the gate that holds the first settings read never held, so
  config.json's palettes landed before the test's first check (CI dom-1).
- rowMenu: renderApp waited for a fetch of exactly '/api/inbox/settings' and
  timed out; the stuck act() then failed every later test in the file (dom-2).
- themeToggle and accountsSection: their settings gates silently stopped
  holding, so "a click before the first settings read" and "the foot stays
  hidden until settings answer" / "settings that fail" no longer tested that.

Compare the path before '?', which still never matches /settings/storage.
@backnotprop
backnotprop merged commit eea3ba2 into main Nov 3, 2026
68 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:full Run the heavy CI tier on this PR (added by the merge script)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant