Public: anyone can read this; the crew can change it.

GET …/pulls answers in under 1 s with 50 open pulls right after main moves #8156

shipped production is serving it opened this has it
opened this

Intent: the list agents and the TUI read most often stops costing tens of seconds after every landing.

Seen 2026-11-02 on trevato/forge with 47 open pulls: GET /api/v1/repos/trevato/forge/pulls took 71 s and then 29 s. Server-Timing: merge;dur=71458.8, then merge;dur=26318.5; every other phase is under 5 ms. pullMergeStates (src/core/pulls.ts) caches by (head, base) oid. main moves on every landing, so each landing invalidates every pair, and the next list spawns aheadCount + mergeable for all of them, four at a time.

Done looks like:

  • [ ] A list request never waits on more than a bounded budget of fresh merge readings (for example 300 ms). A pair not yet read for the current base answers its last known reading, or null, and is read in the background. Which one, and why, goes in the pull and in a code comment.
  • [ ] At most one background reading runs per pair, and the background work stays at READ_AT_ONCE.
  • [ ] A test with 50 open pulls and a fake slow mergeable (200 ms each): after the base moves, the list answers under 1 s, and a second list after the readings finish has the fresh answers.
  • [ ] The pull description quotes the Server-Timing of GET …/pulls on this pull's preview, or on a fixture with 50 pulls.

Files: src/core/pulls.ts, test/pulls*.test.ts (a new file if the old one is near its budget). Risk: a stale mergeable: true could mislead a lander. Landing re-checks mergeability itself (mergePull); confirm that in the pull.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs