perf(state): add messages(session_id, id) index for windowed reads (#76237 salvage) - #76877
Merged
kshitijk4poor merged 1 commit intoAug 2, 2026
Conversation
…ueries Every ORDER BY id query on the messages table sorted or scanned the whole session: get_messages_around's window seek, latest_message_row_id (LIMIT 1), and get_messages' full-load ordering all paid O(session history) per call — hot mid-turn via session_search and reactions. messages.id is an original column (INTEGER PRIMARY KEY AUTOINCREMENT), so the index lives in SCHEMA_SQL next to idx_messages_session — no legacy-column migration hazard (the kanban lesson from NousResearch#28776 does not apply). Measured (real schema, one 20k-message session, median of 30): get_messages_around 7.08 -> 0.22 ms (32x), latest_message_row_id 3.37 -> 0.011 ms (307x), get_messages full load 111.6 -> 98.6 ms (1.13x — remaining cost is row deserialization, not the sort). Window results byte-identical at probe points across the session. Tests: VM-step pin (get_messages_around bounded work, calibrated ~12 vs ~855 handler calls, threshold 300 — fails without the index) and window parity with/without the index. No EXPLAIN/plan text (behavior contracts, AGENTS.md).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Salvage of #76237 by @spfcraze — cherry-picked to preserve authorship. Clean as submitted; no follow-up needed.
Context — what this changes for users
session_search's scroll shape (get_messages_around) — used every time the agent or a user pages through past-conversation context — currently walks the session's whole message history to find the window. On long sessions (thousands of messages) that's a full scan per call. The newmessages(session_id, id)index turns it into an index seek: 32-307x measured, and EXPLAIN-verified (346 VM steps → 2 on the probe workload).Bonus coverage (verified by EXPLAIN probes): the rewind query (
WHERE session_id=? AND id>=?) and last-user-message lookups (ORDER BY id DESC LIMIT 1) also pick up the new index.Review & verification (full pipeline run)
tests/test_hermes_state.pygreen, ruff clean.SCHEMA_SQL(notDEFERRED_INDEX_SQL) is correct —CREATE INDEX IF NOT EXISTSis idempotent for existing DBs.Closes #76237.