Skip to content

fix(store): do not rewrite the whole store on thread select (#636) - #638

Merged
currentbits merged 1 commit into
mainfrom
coder/fork-selecting-a-thread-schedules-a-full-f2c6ab
Aug 21, 2026
Merged

currentbits merged 1 commit into
mainfrom
coder/fork-selecting-a-thread-schedules-a-full-f2c6ab

Conversation

@currentbits

Copy link
Copy Markdown
Owner

Fixes #636.

threads:get stamped lastVisitedAt with store.save(), which armed a debounced flush of the entire ~180 MB JSON blob. Selecting threads at idle was a few hundred ms of main-thread stringify plus 180 MB of SSD writes per click.

Visit now calls store.markDirty(): the stamp stays in memory, the exit hook covers quit, and the next real flush (append, settings, etc.) persists it. Hard crash: unread-dot state is a click stale, which the issue already called acceptable.

Not named touch() — updateThread({ touch: true }) already means bump updatedAt.

Does not touch the streaming-append rewrite tracked in #225.

Test

  • getThreadDetail (the threads:get path) stamps lastVisitedAt without arming _timer
  • markDirty sets _dirty without scheduling a flush; saveNow still persists
  • Existing lastVisitedAt stamp / no-bump-updatedAt / peek / pushDetail tests still pass
node --experimental-strip-types --test electron/test/last-visited.test.js electron/test/store.test.js

threads:get stamped lastVisitedAt via store.save(), which armed a
debounced flush of the entire ~180 MB JSON blob. Clicking through idle
threads wrote gigabytes for one timestamp.

Visit now calls markDirty(): the stamp stays in memory, the exit hook
covers quit, and the next real flush persists it. Hard crash: unread-dot
is a click stale.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@currentbits
currentbits merged commit 80b88d3 into main Aug 21, 2026
2 of 6 checks passed
currentbits pushed a commit that referenced this pull request Aug 21, 2026
Two measured wins against the 180 MB single-file store, on top of the
markDirty change in #638:

- Store._load() snapshots to .bak with COPYFILE_FICLONE: an instant CoW
  clone on APFS instead of a 180 MB byte copy inside the boot chain,
  falling back to a real copy on other filesystems (#637).
- SAVE_DEBOUNCE_MAX_MS 2s -> 15s: under sustained streaming each flush
  stringifies and rewrites the whole store (measured ~6 rewrites / 30 s =
  ~1 GB disk writes and ~24% of a core); the crash-loss window is only the
  transcript tail, which provider session logs restore on resume (#225).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@currentbits
currentbits deleted the coder/fork-selecting-a-thread-schedules-a-full-f2c6ab branch October 3, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Selecting a thread schedules a full 180 MB store rewrite (lastVisitedAt stamp)

1 participant