perf(sessions): Adapter.Session() always builds the session tree; add a cheap SessionSummary for status-only callers #717

Open
opened 2026-09-25 08:50:05 +02:00 by dries · 0 comments
Owner

Follow-up from the perf report (item 9).

Symptom: `internal/platforms/opencode/adapter_session_detail.go:46-73` always runs `attachSessionTree` = `GetSessionTree` + one `GetSessionMessages` per tree node (largest tree here: 126 sessions → 126 queries) purely to compute est-cost, plus the live full-conversation fetch. Callers that only need status/title:

  • `internal/server/queue.go:102` (`TurnRunning`/`LatestMessageState`, every flush/idle edge)
  • `internal/routines/service.go:379` (5 s tick per running run)
  • `internal/server/inbox_sessions.go:33` (per inbox item, 10 s poll)
  • `internal/server/plugin_conversation.go:242` (5 s reconciliation per linked session)
  • `internal/server/handlers_sessions.go:422` (`/api/session/tasks`, up to 20 ids, polled every 2 s while a Task runs) and `:51` (pinned)

Fix: add `SessionSummary(id)` on the adapter (live registry + `db.GetSessionSummary`, now ~0.2 ms) and use it in those callers; make `attachSessionTree` lazy (detail handler only) and compute tree cost from `session.cost/tokens_*` when the schema has them (`DB.sessionTotals`) instead of loading messages.

Follow-up from the perf report (item 9). **Symptom:** \`internal/platforms/opencode/adapter_session_detail.go:46-73\` always runs \`attachSessionTree\` = \`GetSessionTree\` + one \`GetSessionMessages\` per tree node (largest tree here: 126 sessions → 126 queries) purely to compute est-cost, plus the live full-conversation fetch. Callers that only need status/title: - \`internal/server/queue.go:102\` (\`TurnRunning\`/\`LatestMessageState\`, every flush/idle edge) - \`internal/routines/service.go:379\` (5 s tick per running run) - \`internal/server/inbox_sessions.go:33\` (per inbox item, 10 s poll) - \`internal/server/plugin_conversation.go:242\` (5 s reconciliation per linked session) - \`internal/server/handlers_sessions.go:422\` (\`/api/session/tasks\`, up to 20 ids, polled every 2 s while a Task runs) and \`:51\` (pinned) **Fix:** add \`SessionSummary(id)\` on the adapter (live registry + \`db.GetSessionSummary\`, now ~0.2 ms) and use it in those callers; make \`attachSessionTree\` lazy (detail handler only) and compute tree cost from \`session.cost/tokens_*\` when the schema has them (\`DB.sessionTotals\`) instead of loading messages.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dries/ocman#717
No description provided.