Skip to content

perf(dashboard): use GROUP BY for session stats instead of fetching 10k rows - #73362

Merged
kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:salvage/48921-group-by-source
Jul 28, 2026
Merged

perf(dashboard): use GROUP BY for session stats instead of fetching 10k rows#73362
kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:salvage/48921-group-by-source

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

/api/sessions/stats source histogram is now a single GROUP BY query instead of materializing up to 10,000 list_sessions_rich rows, cutting response time from ~575ms to <1ms on large databases.

Changes

  • hermes_state.py: Add session_count_by_source() — single GROUP BY query with exclude_children/include_archived/limit params mirroring list_sessions_rich/session_count filter semantics
  • hermes_cli/web_server.py: Replace list_sessions_rich(limit=10000) loop with db.session_count_by_source() call (−3 lines, try/except guard preserved)
  • tests/test_hermes_state.py: 4 new tests (basic grouping, empty db, child exclusion, COALESCE grouping)
  • tests/hermes_cli/test_dashboard_admin_endpoints.py: 1 new test verifying list_sessions_rich is NOT called by stats endpoint

Fixes from review feedback

Original PR #48921 by @liuhao1024 had 3 issues identified by @teknium1 and @wernerhp:

  1. Removed try/except guard — a DB error now degrades to empty by_source (behavior-neutral), not a 500
  2. GROUP BY source mismatch with SELECT COALESCE(source, 'cli') — fixed to GROUP BY COALESCE(source, 'cli') to prevent duplicate-key data loss
  3. Missing child/delegate exclusion — added exclude_children=True mirroring list_sessions_rich visibility so source counts match what the Sessions page lists

Aggregate shape adapted from closed duplicate #61120 by @mijanx.

Closes #48914
Closes #48921

@alt-glitch alt-glitch added type/perf Performance improvement or optimization P3 Low — cosmetic, nice to have comp/dashboard Web dashboard / control panel UI (dashboard/, landing) needs-decision Awaiting maintainer decision before any implementation labels Jul 28, 2026
…0k rows

Replaces the O(N) list_sessions_rich histogram in /api/sessions/stats
with a single GROUP BY query, reducing response time from ~575ms to
<1ms on large databases.

Original PR NousResearch#48921 by @liuhao1024. Salvage fixes based on review
feedback from teknium1 and @wernerhp:

1. Preserve try/except guard — a DB error still degrades to empty
   by_source instead of failing the whole stats response.
2. GROUP BY COALESCE(source, 'cli') — the original GROUP BY source
   could emit duplicate 'cli' keys (NULL group + literal 'cli' group)
   that the dict comprehension silently dropped.
3. Add exclude_children=True — list_sessions_rich excludes subagent
   runs, delegates, and compression continuations by default; the
   bare GROUP BY counted all rows, inflating source counts.

Aggregate shape (exclude_children/include_archived/limit params)
adapted from closed duplicate NousResearch#61120 by @mijanx.

Closes NousResearch#48914
Co-authored-by: mijanx <mijanx@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/dashboard Web dashboard / control panel UI (dashboard/, landing) needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have type/perf Performance improvement or optimization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(dashboard): /api/sessions/stats fetches 10 000 full session rows to count by source -- O(N) to O(1) fix available

3 participants