Admin — Analytics
The Analytics page is the operator’s tenant-wide view into what the tenant is doing and what it’s spending. Three tabs — Activity, Cost, Performance — switch between views built from the same underlying aggregates.
Route: /analytics?view=activity|cost|performance
File: apps/web/src/routes/_authed/_tenant/analytics.tsx
Layout
Section titled “Layout”A single top-of-page tab toggle switches between the three views. Some deployments still expose an agent selector for legacy performance rows; current cost reporting should be interpreted through the user who initiated or owns the work, with tenant totals preserved. All charts are rendered with Recharts.
Activity view
Section titled “Activity view”The Activity view answers “is the tenant busy, and where is the work happening?”
It shows thread-turn counts rolled up to day buckets over a rolling window. The aggregation is computed client-side from the same thread and turn queries the Threads page uses, filtered by timestamp.
Queries:
ThreadsListQuery— thread-level dataOnThreadTurnUpdatedSubscription— real-time updates so the Activity view stays current as new turns land
Because activity is computed client-side, it’s fast on small tenants and slower on very large ones. A server-side activity aggregate is on the roadmap for tenants with many thousands of daily turns.
Cost view
Section titled “Cost view”The Cost view is the money conversation. It’s backed by server-side aggregation — the GraphQL resolvers pre-compute cost summaries and time series so the UI doesn’t have to re-aggregate from per-turn rows.
Metric cards
Section titled “Metric cards”Six cards across the top:
| Card | Value |
|---|---|
| Total Spend | Sum across LLM, infrastructure, and tools for the period |
| LLM | Spend on model inference |
| Infra | Spend on underlying compute (Lambda, Aurora, S3) |
| Tools | Spend on tool invocations (MCP calls, built-in tools, integrations) |
| Invocations | Count of turn events in the period |
| Cost / Event | Total spend divided by invocations |
Trend chart
Section titled “Trend chart”A stacked bar chart across the last 30 days, split into LLM / Infra / Tools bands. The chart uses CostTimeSeriesQuery with $days: 30.
Budget table
Section titled “Budget table”A budget table shows user-attributed spend next to user-scoped budget policies. Users with configured budgets show percent used and remaining headroom; users without a policy remain visible as unbudgeted spend. System or unattributed cost is shown separately instead of being assigned to an arbitrary human. Tenant-level budget totals remain available as the overall cap for the period.
Cost by user
Section titled “Cost by user”The primary chargeback table is Cost by User: user name, email, event count, budget usage, and spend for the period. Legacy agent identifiers remain useful for trace and audit context, but the current operator question is “which user is responsible for this spend?”
Cost by model
Section titled “Cost by model”A breakdown table: model name, total spend, input tokens, output tokens. Model names are resolved to human-readable labels through ModelCatalogQuery so the UI shows “Claude Sonnet 4.6” rather than anthropic.claude-sonnet-4-6-v1:0.
Queries
Section titled “Queries”| Query | Purpose |
|---|---|
CostSummaryQuery($tenantId) | Top-of-page metric cards |
CostByUserQuery($tenantId) | User chargeback and system spend |
CostByModelQuery($tenantId) | Cost by model table |
CostTimeSeriesQuery($tenantId, $days) | Trend chart |
BudgetStatusQuery($tenantId) | Budget percent used / status badges |
ModelCatalogQuery | Human-readable model labels |
Zustand caching
Section titled “Zustand caching”Cost data is held in useCostStore (Zustand) so the Dashboard and Analytics pages don’t re-fetch it on every navigation. Hydration happens lazily on first access; subsequent reads come from the store.
Performance view
Section titled “Performance view”The Performance view answers “which runtime scopes are slow, which fail, and where are the tokens going?”
The page may take an agent or runtime-scope selector first. Pick the tenant platform agent or exposed scope and the view shows:
- Latency percentiles (p50 / p95 / p99) over time
- Token usage (input and output) over time
- Error rate
Queries for performance pull from thread traces or the audit log’s cost events depending on implementation. The exact query set is light in the current release — the Performance view is the thinnest of the three and leans on ad-hoc queries more than on dedicated resolvers.
Workflows
Section titled “Workflows”Answer “are we on budget this month?”
Section titled “Answer “are we on budget this month?””- Open Analytics → Cost
- Look at the Total Spend metric card and compare to the tenant’s monthly budget
- Check the user budget table for any row in
warningorexceededstatus - If a user is over budget, raise that user’s budget or wait for the billing-period reset before resuming user-owned scheduled work; if the tenant baseline is over budget, review tenant-level budget policy.
Answer “which user is eating tokens?”
Section titled “Answer “which user is eating tokens?””- Open Analytics → Cost
- Scroll to the cost breakdown table
- Sort by total spend descending
- The top row is the top spender
- Cross-reference in Performance view and Threads to see whether it’s high volume or high per-turn cost
Answer “is anything slower than usual?”
Section titled “Answer “is anything slower than usual?””- Open Analytics → Performance
- Pick an agent
- Look at the latency percentile chart
- Compare p95 to the baseline from prior weeks
- If p95 is trending up, check Threads for that agent to find the slow turns
Data sources
Section titled “Data sources”- Cost aggregates — computed server-side from a
cost_eventsor similar per-turn table, rolled up intocost_aggregatesmaterialized views. The UI never sees raw cost rows. - Activity counts — client-side aggregation from the thread and turn queries
- Budget status — derived server-side from user and tenant budget policies where available
- Model catalog — a static catalog maintained alongside the tenant configuration
Known limits
Section titled “Known limits”- Activity is client-computed. For tenants with tens of thousands of daily turns, the Activity view can be slow to render. A server-side activity aggregate is on the Roadmap.
- Performance view is shallow. It shows one scope at a time and lacks a full cross-Space comparison. A fuller performance dashboard is a future improvement.
- Cost attribution is still evolving. System and historical spend without a deterministic user owner appears as system/unattributed cost instead of being assigned speculatively.
- No custom date ranges. The trend chart is fixed to 30 days; longer or shorter windows aren’t exposed in the UI.
Related pages
Section titled “Related pages”- Dashboard — the quick-glance metric cards that the Analytics page backs
- Threads — drill into the specific turns that drove a number
- Tenant Agent — platform-agent defaults and legacy agent context
- Spaces — Space runtime budget overrides
- Budgets, Usage, and Audit (concept) — the control layer
- Roadmap — what’s coming next in cost tracking and eval UI