Bound AI governance session listings to a 180-day window
What changes for users
Value: 180 days, a constant that is easy to raise later if needed. Shared with Nate in #634979.
- The Recent agent sessions card and the Audit events tab list sessions from the last 180 days by default. Today they have no date bound.
- On GitLab.com about 1.5M of 7.85M sessions (19%) started more than 180 days ago. They need a date filter to be seen. A filter wider than 180 days is cut to 180 days, and Show the 180-day session window on the AI Gover... (!265843 - merged) tells the user.
countis capped: above 1,000 it returns 1,001. No page reads it, so only API callers see this.- Why 180: the issue's example of 30 days would also hide sessions from 31 to 180 days ago in those two places. 180 matches the date range limit of value stream analytics and DORA.
The GraphQL field aiGovernanceSessions (groups and projects) now reads at most a 180-day window of sessions, and its count is limited to 1000. Callers that send a window of 180 days or less, or look a session up by id, see no change.
Why
With no sessionStartedAfter, the finder deduplicated a namespace's whole siphon_ai_governance_sessions history before paging and count counted all of it, so the work grew with the history on a server other features share. The PostgreSQL path had the same shape.
On GitLab.com (Database Lab clone of 2026-10-28) ai_governance_sessions holds about 7.85M rows. About 1.5M (19%) started more than 180 days ago, 579k before 2026-01-01, 19k before 2025-07-01 and 2,153 before 2025-01-01, the oldest from the Duo workflow backfill. After this change those need an explicit window to be listed.
The change
sessionStartedAfterdefaults to 180 days beforesessionStartedBeforeor before now, whichever is earlier; an earlier value is moved up to that bound, the same wayfirstis limited by the max page size. Applied inResolvers::Ai::Governance::BaseSessionsResolver, so both finders get it. A lookup byidgets no default window.AiGovernanceSessionConnectioninheritsLimitedCountableConnectionType:counttakes alimitof at most 1000 (default 1000) and returnslimit + 1beyond it.- Argument and field descriptions say so; GraphQL reference and introspection regenerated. No migration.
- No frontend query selects
count. The "Recent agent sessions" card and the Audit events tab list without a window and still show every session newer than 180 days; the drawer looks up byid.
Measured
Local ClickHouse 26.9.2, a scratch copy of the table with 3,000,000 synthetic sessions under one group over 2.8 years, the finder's exact query, first page of 21, peak memory from system.query_log.
| Query | Peak memory | Rows read | Time |
|---|---|---|---|
| Page, no window (before) | 797 MiB | 3,000,000 | 438 ms |
Page, no window, optimize_aggregation_in_order |
217 MiB | 3,000,000 | 2174 ms |
| Page, 180-day window (after) | 158 MiB | 554,906 | 93 ms |
| Page, 30-day window | 140 MiB | 122,778 | 102 ms |
| Exact count, no window (before) | 257 MiB | 3,000,000 | 67 ms |
PostgreSQL, gitlab-org's hierarchy on the production clone (pgolash, 2026-10-30): the count query goes from 83,323 buffers (6.5 s) without a window to 924 buffers with it, an index-only scan on i_ai_governance_sessions_on_namespace_started_at_id with the window in the index condition, stopping at 1,001 rows.
Decisions
- Window, not in-order aggregation: that still reads every row and is five times slower; the table has no partition key, so only a
session_started_atbound prunes. - Clamp, not error, on a span over 180 days: the Audit events tab's date tokens accept any date, so an error would break that tab.
- 180 days as default and cap, not 30: the two unwindowed surfaces stay unchanged except for old sessions, and it matches the value stream and DORA range limit.
- Count limited to 1000: no UI reads it, and the exact count scanned the whole set.
Open question
A 30-day default later would need the card and the Audit events tab to send an explicit window, a separate frontend change.
Ships with
Show the 180-day session window on the AI Gover... (!265843 - merged) (card footnote and Audit events tab note). The two should merge together: if only this MR merges, sessions older than 180 days drop out of those lists with nothing saying so.
What users will see
The frontend MR Show the 180-day session window on the AI Gover... (!265843 - merged) explains the window on both pages. After this change:
- The Recent agent sessions card says which window it covers:

- The Audit events tab says which 180 days are listed when the date filter is wider than that:

Merge order
This change ships in three MRs:
| Order | MR | What it does | Depends on |
|---|---|---|---|
| 1 | Show the 180-day session window on the AI Gover... (!265843 - merged) • Dheeraj Joshi • 19.6 | Frontend notes that explain the window | none |
| 2 | Bound AI governance session listings to a 180-d... (!265842 - merged) • Dheeraj Joshi • 19.6 | Sessions list: 180-day default window and a capped count | !265843 (merged) (merge order, not a GitLab block) |
| 2 | Bound Duo session artifact listings to a 180-da... (!265854 - merged) • Dheeraj Joshi • 19.6 | Session artifacts list: the same window and cap | !265843 (merged) (merge order, not a GitLab block) |
Merge the frontend MR first or together with both backend MRs, on the same day. If only the backend merges, sessions older than 180 days drop out of the lists with nothing saying so.
Related to #635324.

