Skip to content

perf(server): reuse stored turn item positions - #19230

Merged
t3dotgg merged 1 commit into
pingdotgg:mainfrom
tannerpolley:upstream-fix/turn-item-position-reuse
Oct 14, 2026
Merged

t3dotgg merged 1 commit into
pingdotgg:mainfrom
tannerpolley:upstream-fix/turn-item-position-reuse

Conversation

@tannerpolley

Copy link
Copy Markdown
Contributor

Problem

TurnItemPositionStore.allocate runs on every turn-item update. For an item that already has a position it still reads the run ordinal, runs the INSERT … SELECT MAX(ordinal) … ON CONFLICT DO NOTHING, and then reads the stored position back. A streaming message updates the same item many times, so this repeats on the server's database connection for every delta.

Change

Look up the item's stored position first and return it when one exists. First allocation, the conflict handling, the final read and the error mapping are unchanged. The old path already kept an existing item's position (the insert was discarded by ON CONFLICT), so the result is the same; only the redundant work goes away.

Scope and approval

This is a small, focused performance fix with no behavior change: 8 lines in the existing store plus one test. No schema, contract, ordering or provider change.

#18094 also edits this function (to assign timeline bands when runs start). It doesn't add this shortcut; whichever lands second needs a trivial rebase.

Verification

  • New test TurnItemPositionStore.test.ts: a temporary BEFORE INSERT trigger rejects any insert for an item that already has a position. Updating an existing item, after another item was allocated, after a run change, and the same item ID in another thread all return the expected ordinals. The test fails on the current code (the redundant insert hits the trigger) and passes with the change.
  • vp test run apps/server/src/orchestration-v2/TurnItemPositionStore.test.ts apps/server/src/orchestration-v2/FoundationPersistence.test.ts: 43 passed. Server tsc-rs --noEmit, targeted vp lint and vp fmt --check pass.

Benchmark on Linux, Node 22: a fresh file-backed SQLite database per sample, built with the project's own persistence layer and migrations (WAL), 2,000 stored positions, 20,000 sequential updates cycling through 100 existing items, 2,000 warmup updates excluded, 7 alternating samples per version.

20,000 existing-item updates Before After
Median 901 ms 282 ms
Range 820–969 ms 248–366 ms

That is about 3.2× less time in the allocator. This measures the allocator only, not end-to-end streaming latency.

Built with Codex (GPT-6.1 Sol) and Claude Code (Opus 5.5).

🤖 Generated with Claude Code

Return an item's durable position before attempting another allocation.
Cover repeated updates with a SQLite trigger that rejects redundant inserts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Oct 14, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at f70f891

Macroscope's review found this PR approvable — This is a small, self-contained performance optimization that reuses an existing stored ordinal without changing allocation results or schemas. New coverage verifies the reuse path and leaves first-time allocation behavior unchanged.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 14, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9d634d7a-8f5e-4684-906a-11f6351fc572
📥 Commits

Reviewing files that changed from the base of the PR and between 11fd54f and f70f891.

📒 Files selected for processing: 2
  • apps/server/src/orchestration-v2/TurnItemPositionStore.test.ts
  • apps/server/src/orchestration-v2/TurnItemPositionStore.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

TurnItemPositionStoreV2.allocate now returns an existing ordinal for the same thread and turn item before attempting new allocation. A SQLite test checks position reuse, next-position allocation, and independent numbering across threads.

Changes: Turn item position allocation

Layer / File(s) Summary
Existing-position reuse and validation
apps/server/src/orchestration-v2/TurnItemPositionStore.ts, apps/server/src/orchestration-v2/TurnItemPositionStore.test.ts
allocate returns the existing ordinal for the same thread and turn item. The test verifies reuse with changed run metadata, next-position allocation, and numbering for another thread.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Refactor

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to f70f8

No actionable issue remains from this review; the PR is mergeable after normal checks.

Pre-merge checks: Passed 4
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: reusing stored turn item positions in the server.
Description check Passed The description includes the problem, change, scope and approval rationale, targeted verification, test results, benchmark details, and limitations. It matches the required template and explains the p…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@t3dotgg
t3dotgg merged commit 8855a6d into pingdotgg:main Oct 14, 2026
29 checks passed
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Oct 14, 2026
## What's Changed
* chore(deps): Effect 4.0.4 and OpenCode 2.0.28, dropping the patches they made unnecessary by @juliusmarminge in pingdotgg/t3code#19213
* fix(server): a Claude 403 no longer tells you to log in again by @shivamhwp in pingdotgg/t3code#15872
* fix(server): persist only changed pull request links by @juliusmarminge in pingdotgg/t3code#19248
* fix(server): delegate_task explains that supervised runtime modes pause the child by @saphid in pingdotgg/t3code#14416
* fix(server): Claude subagent progress no longer re-stores the unchanged prompt by @Gigioxx in pingdotgg/t3code#18375
* fix(server): thread list reads no longer freeze the server on large databases by @t3dotgg in pingdotgg/t3code#19226
* perf(server): streamed events no longer rewrite the whole thread row by @Baker-Harrison in pingdotgg/t3code#18890
* docs: close PRs written by Gemini or Muse Wonder by @t3dotgg in pingdotgg/t3code#19286
* fix: update all no longer runs agents twice or loses background work by @t3dotgg in pingdotgg/t3code#19291
* fix(server): enforce one database owner and guard update rollback by @maria-rcks in pingdotgg/t3code#16102
* perf(server): reuse stored turn item positions by @tannerpolley in pingdotgg/t3code#19230
* perf(server): avoid quadratic resource history replay by @saphid in pingdotgg/t3code#18825
* fix(server): repair ownership UUID generation by @t3dotgg in pingdotgg/t3code#19298
* fix(client-runtime): slow config snapshots no longer drop working connections by @saphid in pingdotgg/t3code#14518
* fix(server): bound activity publishes so stalled responses release the worker by @saphid in pingdotgg/t3code#18830
* perf(shared): cached SQLite statements no longer hold large parameters by @t3dotgg in pingdotgg/t3code#19305
* fix(provider-cursor): Cursor text generation no longer leaks SQLite file handles on every call by @t3dotgg in pingdotgg/t3code#19310
* fix(server): make SQLite checkpoints durable on macOS by @t3dotgg in pingdotgg/t3code#19304
* perf(server): Codex plan streaming no longer commits every token by @t3dotgg in pingdotgg/t3code#19317
* fix(server): large file edits no longer store their full diff twice by @t3dotgg in pingdotgg/t3code#19316
* fix(web): settings save again after a stored value fails decode by @t3dotgg in pingdotgg/t3code#19312
* fix(server): HTML and Markdown attachments no longer fail OpenCode turns by @t3dotgg in pingdotgg/t3code#19319
* fix(server): worktree paths no longer vanish on git before 2.36 by @t3dotgg in pingdotgg/t3code#19315
* fix(acp): custom models now reach the agent instead of failing to open by @t3dotgg in pingdotgg/t3code#19313
* fix(server): Claude no longer shows unavailable when its health check can't run in $HOME by @t3dotgg in pingdotgg/t3code#19320
* fix(server): stalled OAuth token requests no longer block credential calls by @t3dotgg in pingdotgg/t3code#19321
* fix(server): steered Claude turns no longer undercount token usage by @t3dotgg in pingdotgg/t3code#19314
* fix(server): closing a Claude session no longer leaves plugin MCP servers running by @t3dotgg in pingdotgg/t3code#19322
* fix(client-runtime): T3 Connect link timeouts explain the relay 504 by @t3dotgg in pingdotgg/t3code#19329
* fix(web): settle shortcut moves to the next thread like the sidebar by @t3dotgg in pingdotgg/t3code#19328
* fix(acp): Copilot's default agent no longer disappears from the Agent menu by @t3dotgg in pingdotgg/t3code#19330
* perf(server): SQLite checkpoints no longer block the event loop by @t3dotgg in pingdotgg/t3code#19324
* fix(mobile): incompatible environments now say whether to update the app or the host by @t3dotgg in pingdotgg/t3code#19331
* fix(web): live reasoning stays scrolled to the newest text while it streams by @t3dotgg in pingdotgg/t3code#19334
* fix(server): T3 Connect no longer stays down after a network change by @t3dotgg in pingdotgg/t3code#19335
* fix(clients): host images say when the connection lacks file access by @t3dotgg in pingdotgg/t3code#19337
* fix(clients): a resumed subagent no longer moves the later turn's Worked for row by @t3dotgg in pingdotgg/t3code#19338
* fix: Claude and Codex no longer time out behind mise wrappers by @t3dotgg in pingdotgg/t3code#19340
* perf(server): turns no longer re-read merged PRs from GitHub by @t3dotgg in pingdotgg/t3code#19344
* docs(settings): explain that provider update checks also gate the model catalog by @fixfon in pingdotgg/t3code#18208
* fix(web): an unsaved citation comment survives a question or approval by @t3dotgg in pingdotgg/t3code#19350
* fix(server): changing Claude effort no longer fails while background agents run by @t3dotgg in pingdotgg/t3code#19341
* fix(server): service updates no longer fail on full disks or large databases by @t3dotgg in pingdotgg/t3code#19311

## New Contributors
* @Baker-Harrison made their first contribution in pingdotgg/t3code#18890
* @tannerpolley made their first contribution in pingdotgg/t3code#19230

**Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261014.3093...v0.0.46-nightly.20261014.3105

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261014.3105
github-actions Bot added a commit to davidvanderklay/t3code-flake that referenced this pull request Oct 14, 2026
## What's Changed
* chore(deps): Effect 4.0.4 and OpenCode 2.0.28, dropping the patches they made unnecessary by @juliusmarminge in pingdotgg/t3code#19213
* fix(server): a Claude 403 no longer tells you to log in again by @shivamhwp in pingdotgg/t3code#15872
* fix(server): persist only changed pull request links by @juliusmarminge in pingdotgg/t3code#19248
* fix(server): delegate_task explains that supervised runtime modes pause the child by @saphid in pingdotgg/t3code#14416
* fix(server): Claude subagent progress no longer re-stores the unchanged prompt by @Gigioxx in pingdotgg/t3code#18375
* fix(server): thread list reads no longer freeze the server on large databases by @t3dotgg in pingdotgg/t3code#19226
* perf(server): streamed events no longer rewrite the whole thread row by @Baker-Harrison in pingdotgg/t3code#18890
* docs: close PRs written by Gemini or Muse Wonder by @t3dotgg in pingdotgg/t3code#19286
* fix: update all no longer runs agents twice or loses background work by @t3dotgg in pingdotgg/t3code#19291
* fix(server): enforce one database owner and guard update rollback by @maria-rcks in pingdotgg/t3code#16102
* perf(server): reuse stored turn item positions by @tannerpolley in pingdotgg/t3code#19230
* perf(server): avoid quadratic resource history replay by @saphid in pingdotgg/t3code#18825
* fix(server): repair ownership UUID generation by @t3dotgg in pingdotgg/t3code#19298
* fix(client-runtime): slow config snapshots no longer drop working connections by @saphid in pingdotgg/t3code#14518
* fix(server): bound activity publishes so stalled responses release the worker by @saphid in pingdotgg/t3code#18830
* perf(shared): cached SQLite statements no longer hold large parameters by @t3dotgg in pingdotgg/t3code#19305
* fix(provider-cursor): Cursor text generation no longer leaks SQLite file handles on every call by @t3dotgg in pingdotgg/t3code#19310
* fix(server): make SQLite checkpoints durable on macOS by @t3dotgg in pingdotgg/t3code#19304
* perf(server): Codex plan streaming no longer commits every token by @t3dotgg in pingdotgg/t3code#19317
* fix(server): large file edits no longer store their full diff twice by @t3dotgg in pingdotgg/t3code#19316
* fix(web): settings save again after a stored value fails decode by @t3dotgg in pingdotgg/t3code#19312
* fix(server): HTML and Markdown attachments no longer fail OpenCode turns by @t3dotgg in pingdotgg/t3code#19319
* fix(server): worktree paths no longer vanish on git before 2.36 by @t3dotgg in pingdotgg/t3code#19315
* fix(acp): custom models now reach the agent instead of failing to open by @t3dotgg in pingdotgg/t3code#19313
* fix(server): Claude no longer shows unavailable when its health check can't run in $HOME by @t3dotgg in pingdotgg/t3code#19320
* fix(server): stalled OAuth token requests no longer block credential calls by @t3dotgg in pingdotgg/t3code#19321
* fix(server): steered Claude turns no longer undercount token usage by @t3dotgg in pingdotgg/t3code#19314
* fix(server): closing a Claude session no longer leaves plugin MCP servers running by @t3dotgg in pingdotgg/t3code#19322
* fix(client-runtime): T3 Connect link timeouts explain the relay 504 by @t3dotgg in pingdotgg/t3code#19329
* fix(web): settle shortcut moves to the next thread like the sidebar by @t3dotgg in pingdotgg/t3code#19328
* fix(acp): Copilot's default agent no longer disappears from the Agent menu by @t3dotgg in pingdotgg/t3code#19330
* perf(server): SQLite checkpoints no longer block the event loop by @t3dotgg in pingdotgg/t3code#19324
* fix(mobile): incompatible environments now say whether to update the app or the host by @t3dotgg in pingdotgg/t3code#19331
* fix(web): live reasoning stays scrolled to the newest text while it streams by @t3dotgg in pingdotgg/t3code#19334
* fix(server): T3 Connect no longer stays down after a network change by @t3dotgg in pingdotgg/t3code#19335
* fix(clients): host images say when the connection lacks file access by @t3dotgg in pingdotgg/t3code#19337
* fix(clients): a resumed subagent no longer moves the later turn's Worked for row by @t3dotgg in pingdotgg/t3code#19338
* fix: Claude and Codex no longer time out behind mise wrappers by @t3dotgg in pingdotgg/t3code#19340
* perf(server): turns no longer re-read merged PRs from GitHub by @t3dotgg in pingdotgg/t3code#19344
* docs(settings): explain that provider update checks also gate the model catalog by @fixfon in pingdotgg/t3code#18208
* fix(web): an unsaved citation comment survives a question or approval by @t3dotgg in pingdotgg/t3code#19350
* fix(server): changing Claude effort no longer fails while background agents run by @t3dotgg in pingdotgg/t3code#19341
* fix(server): service updates no longer fail on full disks or large databases by @t3dotgg in pingdotgg/t3code#19311

## New Contributors
* @Baker-Harrison made their first contribution in pingdotgg/t3code#18890
* @tannerpolley made their first contribution in pingdotgg/t3code#19230

**Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261014.3093...v0.0.46-nightly.20261014.3105

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261014.3105
@tannerpolley
tannerpolley deleted the upstream-fix/turn-item-position-reuse branch October 15, 2026 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants