Prefetch timeline, queue, and approvals with thread bootstrap - #3
Merged
Conversation
Opening a thread waited for GET /threads/:id before starting the payloads the view needs next. Start those reads in the same turn so React Query joins in-flight work instead of a second serial round. Fixes get-bb#1303
This was referenced Sep 2, 2026
…ttles. Phase log records sidecar-reads-started while the include GET is still pending, then requires that mark to precede bootstrap-settled.
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.
Human comments
What was wrong
Opening a thread waited for
GET /threads/:id?include=environment,hostto settle, then started timeline, queued messages, and pending interactions. First paint of the thread chrome paid a serial waterfall. Related: get-bb/bb#1303 (~19 requests on open).This is
apps/app(web and Electron). The daemon already serves those three reads; the client just started them too late.What changed
useThreadDetailBootstrapstill returns the same bootstrap GET.prefetchQuerys timeline, queued messages, and pending interactions, so React Query joins in-flight work instead of waiting for bootstrap to settle.timelinePrefetchflag. AppLayout no longer has to opt in; ThreadDetailView gets the same start.Wire shape is unchanged. This is not a
GET /threads/:id/openpayload. NoHOST_DAEMON_PROTOCOL_VERSIONbump.Why this way
T3’s rule is: do less work before the thread view can paint. Collapsing everything into one subscribe payload (
GET /threads/:id/open) is the later cut — new wire, enrolled daemons would need an update.This PR only kills the waterfall we already own on the client: three reads that do not need environment can start immediately. Git work-status and pull-request reads still need environment, so they stay after bootstrap. Bundling those into bootstrap would either over-fetch or invent the one-payload API we are not shipping here.
Benefit to bb
Every thread open, web and desktop. Timeline, queue, and approvals start in the same turn as the include GET, so the thread view can paint chrome and fill the list from in-flight requests instead of a second serial round. Existing daemons keep working.
Already opened upstream: get-bb/bb#2935.
Harvest
Independent. Already on get-bb. Pairs with Datahazed #6 (paint from cache) and #7/#8 (start bootstrap earlier) but none of those are required for this PR to be correct.
Decision record: docs/perf-control-plane.md (PR #9).
How you verified
Phase-order test (
apps/app/src/test/perf-phase.ts) recordssidecar-reads-startedwhile the include GET is still pending, then requires that mark to precedebootstrap-settled. Reverting to a waterfall fails this test.apps/app/src/hooks/queries/thread-queries.test.tsxasserts timeline, queued messages, and pending interactions are requested before bootstrap settles. 22 passed.Related: get-bb#1303, get-bb#2935