You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
t3_queue and the handoff-tool analytics lookup read a long thread's whole message history #36125
Two MCP paths read every message of a long thread to use a handful. On our two coordinator threads, they cost 36 minutes of reader time in 8.6 hours. Both paths are unchanged on main at a044f0c0b3.
Measured in production on 0.1.10-nightly.20261112.4606; our local patches do not touch these paths. Thread A has 7,511 runs and thread B 6,939; each has 14,000–17,400 messages. statev2.sqlite is 49 GB.
1. t3_queue list and read: about 7.7 s per call
t3_queue list and read call readThread(threadId, ["runs", "messages"]). That loads every run and every message of all roles, then keeps the queued runs and their messages (queuedRunsInDeliveryOrder, queueEntry). In 8.6 hours, 212 calls on the two threads:
Read
Rows
Median
Messages, all roles
14,300–17,400
2.9 s
Message ordering over user_message items
11,500–11,800
3.7 s
Runs
6,900–7,500
1.1 s
That is 7.7 s per call and 29 minutes in total. An agent that checks its own queue at every wake pays this each time, and once more for each t3_queue read of a truncated item. Both actions need only the queued runs (runStatuses: ["queued"]) and their user messages.
2. Analytics for handoff tools: about 3.9 s per call
After each handoff tool call, such as t3_thread_send or delegate_task, the analytics record runs scheduledRunOf. It reads the caller's active run by id, but all of the thread's user messages, to check whether that run's message has a scheduledTaskId. It is forked off the response, but it still occupies a reader: 117 calls took 3.0 s for the user messages (up to 7,932 rows) plus 0.9 s for their ordering, 7.8 minutes in total. Reading only the run's own message, by messageIds or messageRunIds, would make it a keyed read.
Times are statement execution times from a local statement log that records every read over 250 ms, so the counts are complete for these threads. #36095 covered two similar paths, and #36100 fixed them.
Measured and written by Claude (Opus 5.5) in T3 Code; posted with the owner's approval.
#36130 fixes both reads on our database. These are the store reads #36130 now makes, run through the real ProjectionStore on main at a044f0c0b3. The database is a block clone of our 49 GB statev2.sqlite, read-only, and the times are from the second of two passes. Thread A has 7,352 runs and 17,066 messages.
Read
Before
After
t3_queue list or read
7.1 s
5 ms
Handoff analytics (scheduledRunOf)
3.8 s
4 ms
Two queue actions still read the whole history in their command preflight, which holds the thread's dispatch lock:
queued-run.edit reads all runs, user messages and user-message items: 4.9 s.
Activity
Dropje97 commentedon Nov 13, 2026
#36130 fixes both reads on our database. These are the store reads #36130 now makes, run through the real
ProjectionStoreonmainata044f0c0b3. The database is a block clone of our 49 GBstatev2.sqlite, read-only, and the times are from the second of two passes. Thread A has 7,352 runs and 17,066 messages.t3_queuelist or readscheduledRunOf)Two queue actions still read the whole history in their command preflight, which holds the thread's dispatch lock:
queued-run.editreads all runs, user messages and user-message items: 4.9 s.queued-run.reorderreads all runs and user messages: 5.0 s.Measured and written by Claude (Opus 5.5) in T3 Code; posted with the owner's approval.