Skip to content

perf(server): cache the open-PR lookup per worktree and branch - #330

Open
Iaroslav (Rick) Postovalov (CommanderTvis) wants to merge 1 commit into
JetBrains:mainfrom
CommanderTvis:perf/cache-branch-review-lookup
Open

perf(server): cache the open-PR lookup per worktree and branch#330
Iaroslav (Rick) Postovalov (CommanderTvis) wants to merge 1 commit into
JetBrains:mainfrom
CommanderTvis:perf/cache-branch-review-lookup

Conversation

@CommanderTvis

@CommanderTvis Iaroslav (Rick) Postovalov (CommanderTvis) commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Every workspace activation asked the host for the branch's open PR/MR, and so did every window focus — and the host answered by shelling out to gh pr list, a round trip to GitHub measured at 430–560 ms per click, in front of ~20 ms of blocking git config/git remote probes on an event loop that runs git synchronously. Clicking between two worktrees re-queried both, forever, for an answer that changes only when someone opens a PR.

The lookup now remembers what it last answered, per worktree and branch, for 60 s, and concurrent askers share one in-flight call. A null is cached like any other answer: "no PR" is the common case and the expensive one to re-derive.

Two things invalidate an entry rather than letting it go stale:

  • the repo-metadata nudge drops the worktree's entry, so a PR opened or a branch switched underneath converges on the signal that already refreshes the branch label instead of waiting out the TTL;
  • openPr drops it on a successful outcome — opening a PR from the app is the one moment the cached answer stops being true without any git-metadata write to notice it, and without this the chip would keep reading "no PR" for the rest of the TTL.

Measured on the same host and repo, switching between two worktrees: the lookup falls from ~450 ms to 0, leaving git.status (50–70 ms) as the largest remaining per-switch cost.

Verification

check:deps, check:seams, lint, and typecheck pass.

Unit tests: 2 fail — pre-existing and environmental (git.test.ts forces a signing failure via gpg.program, which a machine configured with gpg.format=ssh ignores in favour of gpg.ssh.program, so the commit succeeds and the assertion doesn't hold).

The speedup is noticeable on my laptop.

🤖 Generated with Claude Code

Every workspace activation asked the host for the branch's open PR/MR, and so
did every window focus — and the host answered by shelling out to `gh pr list`,
a round trip to GitHub measured at 430-560 ms per click on this machine, in
front of ~20 ms of blocking `git config`/`git remote` probes on an event loop
that runs git synchronously. Clicking between two worktrees re-queried both,
forever, for an answer that changes when someone opens a PR.

The lookup now remembers what it last answered, per worktree and branch, and
concurrent askers share one in-flight call. A `null` is cached like any other
answer: "no PR" is the common case and the expensive one to re-derive. The
repo-metadata nudge drops the entry for that worktree, so a PR opened or a
branch switched underneath converges on the signal that already refreshes the
branch label instead of waiting out the TTL.

Opening a PR from the app is the one moment the cached answer stops being true
without any git-metadata write to notice it, so `openPr` drops the worktree's
entry on a successful outcome rather than leaving the chip reading "no PR" for
the rest of the TTL.

Measured on the same host and repo, switching between two worktrees: the
lookup falls from ~450 ms to 0, leaving `git.status` (50-70 ms) as the largest
remaining per-switch cost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUpDgKcBq6XUXdZc6zwvz3
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.

1 participant