Repository navigation
perf(admin): read dashboard ledger usage one bounded scan per entity - #9448
Conversation
The dashboard's per-entity usage was one statement OR-ing every entity's period, which the planner can only answer with a BitmapOr and a heap fetch per matched ledger row, and its count(distinct execution_id) needed the heap anyway because no index carries execution_id. Each read is now a UNION ALL with one arm per entity, so spend is an index-only scan on the existing covering cost indexes, and workflow runs are a separate statement on a new partial index over workflow rows that carries execution_id. The four copies of the period predicate now come from buildUsageAnalyticsScope. What the dashboard shows is unchanged: a run is still a distinct execution_id among the entity's workflow rows in the period. The reads stay on the primary: the replica serves these scans from disk and cancels statements held past its replay delay.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
[Medium impact] The changes since the previous review appear safe to merge. SummaryThe dashboard now reads spend and workflow counts separately, with one
|
There was a problem hiding this comment.
All reported issues were addressed across 8 files
Reply with feedback, questions, or to request a fix.
Turn on auto-fix | Re-trigger cubic
…exes Drops the workflow-runs index and its migration: an extra write on every workflow ledger insert is not worth paying for a staff-only page. Spend stays index-only per entity; the separate run-count statement fetches the matched workflow rows from the heap on the existing period and created_at indexes.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 4 files
Reply with feedback, questions, or to request a fix.
Turn on auto-fix | Re-trigger cubic
Summary
The admin dashboard computed each page's per-entity spend and workflow runs in one statement that OR'd every entity's period together. The planner answers that with a
BitmapOrand a heap fetch for every matched ledger row, or with a scan over every organization entry in the period index, filtered row by row. Both run on the primary.UNION ALLwith one arm per entity. Every arm is bounded by that entity's period on the existing indexes:usage_log_billing_entity_period_cost_idxfor stamped periods andusage_log_billing_entity_created_at_cost_idxfor reporting periods.execution_id, so this statement fetches each matched workflow row from the heap. Keeping it separate leaves the spend scans index-only. A dedicated index was rejected: it would add a write to every workflow ledger insert to speed up a staff-only page.buildUsageAnalyticsScope, which already defines the reporting-vs-stamped period predicate for usage analytics.What the dashboard shows is unchanged. A workflow run is still a distinct
execution_idamong the entity'ssource = 'workflow'ledger rows in the period. Execution logs are not a substitute: they are subject to retention, they include runs with no billed lines, and they don't record which entity a run was billed to.No schema change.
Type of Change
Testing
dashboard-usage.integration.tsruns against real Postgres. It checks spend and run counts per entity, per user, filtered by user, and for historical actors. The seed covers:workflow-testexecution_idEXPLAINon the primary), for a large yearly reporting period plus a stamped period:sourcein the index condition. There is no sequential scan anywhere.check:migrations(no new migrations),drizzle-kit generate(no changes),check:audits,type-check,lint, and thelib/adminunit tests all pass.Checklist