Repository navigation
perf(relay): coalesce startup snapshot writes across discovery batches - #2593
Draft
kalvinnchau wants to merge 1 commit into
Draft
kalvinnchau wants to merge 1 commit into
kalvinnchau wants to merge 1 commit into
Conversation
applyDiscovery called saveDiscovery synchronously per accepted non-cached batch, rebuilding savedEvents() and writing the whole startup snapshot (structured clone, byteSize, getAll) once per batch during catch-up. write at most once per 500 ms window instead, sharing the pending save that profile-triggered saves already use. a batch that revokes access still saves immediately so denied channel content and profiles never linger in the snapshot. pending saves are dropped on dispose, clearCache and denyAll, as before, so a quit within 500 ms of a batch skips that snapshot update. Signed-off-by: Kalvin C <kalvin@squareup.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
At startup the session catches up channel rosters and metadata as many small live discovery batches.
applyDiscoverycalledsaveDiscovery()synchronously for every accepted batch that was not served from cache. Each call rebuiltsavedEvents()and the saved profiles, and wrote the whole startup snapshot, which the IndexedDB adapter structured-clones and sizes. A community with 300 channels paid for 300 full snapshot writes on the main thread during catch-up, all but the last of them superseded immediately.Change
applyDiscoveryschedules the save on the existingdiscoverySavetimer (discoverySave ??= setTimeout(saveDiscovery, 500)), the same pending save that profile-triggered saves already use. So the store writes at most once per 500 ms window, andsaveDiscoveryreads the current state when it fires. A batch that revokes access to a known channel still saves immediately, so a denied channel's events and profiles never stay in the snapshot.No behavior changes
The snapshot is only read by
restoreStartupon the next launch, which already rejects old snapshots and skips them once live discovery has been observed. Pending saves are dropped on dispose,clearCacheand the access-denied reset, as before. The difference is timing:Three startup tests that read the snapshot right after such a read now wait for the write. A new test checks that 5 batches produce one write with the final content after 500 ms. It fails on main (5 writes).
Evidence
Bench: a startup catch-up burst of 300 roster batches (one per channel, 40 members each), delivered through the session's live receive path. The persistence stub structured-clones and serializes each startup patch, standing in for the IndexedDB write. Medians, stock and this PR interleaved on 3 Linux and 3 macOS workstations.
Lower is better. There are 18 samples per cell. These are Node timings without CPU throttling. The burst time excludes the single deferred write, and the stub understates a real IndexedDB write, so the saving in the app is at least this large.
Checks: the relay unit suites pass, along with
tscandbiome.🤖 Generated with Claude Code