Skip to content

perf: parallelize gt status to eliminate N+1 bd subprocess bottleneck#3504

Open
mmlac wants to merge 2 commits intogastownhall:mainfrom
mmlac:fix/gt-status-speed
Open

perf: parallelize gt status to eliminate N+1 bd subprocess bottleneck#3504
mmlac wants to merge 2 commits intogastownhall:mainfrom
mmlac:fix/gt-status-speed

Conversation

@mmlac
Copy link
Copy Markdown
Contributor

@mmlac mmlac commented Apr 2, 2026

Summary

  • Batch hook discovery: New FindAllHandoffBeads() fetches all pinned beads in a single bd call, replacing the N+1 pattern where each agent triggered a separate bd subprocess (~27 calls → 1 per rig)
  • Parallelize within-rig: Hook discovery, MQ summary, and agent runtime checks now run concurrently within each rig goroutine via sync.WaitGroup
  • Batch MQ summary: Single bd list --status=all call split in memory, replacing 2 sequential calls per rig
  • Parallelize tmux/git in gt rig status: HasSession, CurrentBranch, and git Status checks for polecats and crew workers run in parallel goroutines

Reduces total bd subprocess calls from ~45 to ~4 for a typical 3-rig workspace. Expected improvement from >60s to a few seconds.

Files changed

  • internal/beads/handoff.go — Added FindAllHandoffBeads() batch method
  • internal/cmd/status.go — Rewrote discoverRigHooks() to use batch fetch + in-memory resolution; parallelized intra-rig work; batched MQ queries
  • internal/cmd/rig.go — Parallelized polecat and crew status checks in runRigStatus()

Test plan

  • go build ./... passes
  • go test ./internal/beads/... passes
  • Manual: gt status completes in <10s on a multi-rig workspace
  • Manual: gt rig status <rig> completes in <5s with many polecats
  • Manual: gt status --fast still works (skips hooks/MQ as before)
  • Verify hook indicators still show correctly in gt status output. (note: the hook indicators didn't show for me before this, either)

🤖 Generated with Claude Code

gt status was taking >60s due to sequential bd subprocess calls — one per
agent for hook discovery, plus two per rig for MQ summary. This commit
applies four fixes:

1. Batch hook discovery: new FindAllHandoffBeads() fetches all pinned
   beads in a single bd call, replacing N per-agent subprocess calls.

2. Parallelize within-rig: hook discovery, MQ summary, and agent
   runtime checks now run concurrently within each rig goroutine.

3. Batch MQ summary: single bd list call with status=all, split
   open vs in_progress in memory (was 2 separate calls per rig).

4. Parallelize tmux/git in gt rig status: HasSession, CurrentBranch,
   and git Status checks for polecats and crew run in parallel.

Reduces bd subprocess calls from ~45 to ~4 for a typical 3-rig setup.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

Executed-By: mayor
@github-actions github-actions bot added the status/needs-triage Inbox — we haven't looked at it yet label Apr 2, 2026
The dominant bottleneck was polecatMgr.List() which called loadFromBeads()
sequentially for each polecat — each doing 3-6 bd/git subprocess calls.
With 7 polecats this took ~56s.

Changes:
- Parallelize polecat.Manager.List(): load all polecats concurrently
  via goroutines instead of sequential loop
- Restructure runRigStatus to gather ALL data in parallel before display:
  witness IsRunning, refinery IsRunning+Queue, polecatMgr.List, and
  crewMgr.List now run concurrently, then HasSession checks run in a
  second parallel wave

Result: gt rig status drops from ~70s to ~20s (limited by slowest
single polecat's loadFromBeads).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

Executed-By: mayor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/needs-triage Inbox — we haven't looked at it yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant