Skip to content

perf(inbox): index the 1.5s poll hot paths + bound the inbox feed (v0.265.3)#465

Merged
vikasprogrammer merged 1 commit into
mainfrom
feat/inbox-perf
Jul 24, 2026
Merged

perf(inbox): index the 1.5s poll hot paths + bound the inbox feed (v0.265.3)#465
vikasprogrammer merged 1 commit into
mainfrom
feat/inbox-perf

Conversation

@vikasprogrammer

Copy link
Copy Markdown
Owner

Why

The console polls /api/messages (listMessages) and /api/sessions (listSessions) every 1.5s per open tab, and node:sqlite is synchronous — a slow query on either blocks the entire server event loop. On data-heavy tenants (e.g. instawp) this surfaced as laggy approval/inbox notifications and contributed to the server feeling unresponsive. Both queries were full-table scans + sorts, growing with all-time history.

What

  • Hot-path indexes matching each poll's WHERE + ORDER BY:
    • messages(dismissed_at, created_at) — the inbox feed
    • term_sessions(archived_at, created_at) — the session list
    • audit_events(run_id, type, ts) — the per-live-session insight tallies (stampInsights, run every poll)
  • Bounded listMessages to the newest 500 non-dismissed cards, so a pathological undismissed backlog can't grow per-poll cost without limit (owner/admin see all; mine narrows further downstream; mark-all-read/dismiss iterate the same capped list).

message_state's (message_id, member_id) join is already served by its composite PRIMARY KEY — no new index needed there.

Verification

  • npm run typecheck + npm run build clean.
  • EXPLAIN QUERY PLAN on all four hot queries: each now SEARCH ... USING INDEX with no USE TEMP B-TREE FOR ORDER BY (the index satisfies the sort).

Indexes apply to existing DBs on next boot (engine-level, not JSON policy).

🤖 Generated with Claude Code

….265.3)

The console polls /api/messages (listMessages) and /api/sessions (listSessions)
every 1.5s per open tab. node:sqlite is synchronous, so a slow query on either
blocks the whole server event loop — surfacing as laggy approval/inbox
notifications and contributing to the server feeling unresponsive on tenants
with a large history.

- Add hot-path indexes matching each poll's WHERE + ORDER BY:
    messages(dismissed_at, created_at)
    term_sessions(archived_at, created_at)
    audit_events(run_id, type, ts)   -- stampInsights per-live-session tallies
  EXPLAIN QUERY PLAN confirms all now use the index with no temp b-tree sort.
- Bound listMessages to the newest 500 non-dismissed cards so a pathological
  undismissed backlog can't grow the per-poll cost without limit (owner/admin
  see all; the `mine` scope narrows further downstream).

Indexes apply to existing DBs on next boot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPLeBNcNJiURPKiUZ6iMmF
@vikasprogrammer vikasprogrammer changed the title perf(inbox): index the 1.5s poll hot paths + bound the inbox feed (v0.265.2) perf(inbox): index the 1.5s poll hot paths + bound the inbox feed (v0.265.3) Jul 24, 2026
@vikasprogrammer
vikasprogrammer merged commit 7e3bb48 into main Jul 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant