What goes in an LLM spend overview dashboard?
An LLM spend overview dashboard is the page leadership actually opens: what the LLM layer costs, where the spend concentrates, and whether growth is usage or waste. It's built from daily usage rollups synced from a gateway or tracing tool — not from invoices, which arrive too late to act on.
Which cards belong on this dashboard?
- Total LLM spend, trailing 30 days (number + trend)
- Spend per day and per week (line)
- Spend by model (bar)
- Spend by app or team (stacked bar)
- Month-over-month spend growth (number + trend)
- Cost per request trend (line)
- Spend on failed or retried requests (bar)
- Spend vs. budget by team, where budgets exist (table)
What data does this dashboard need?
- Daily usage rollups per model and app: requests, prompt and completion tokens, cost
- App, feature, and team tags carried from request metadata
- Error and retry counts so failed-request spend is visible
- Budgets or targets per team for the variance view
- Cache and batch discount fields where the source records them
How do you build it?
- Sync usage rollups from your LLM gateway, tracing, or eval tool into a database, keeping stable IDs, timestamps, token counts, and costs.
- Build clean models at the grain this dashboard requires — daily per app and model is the workhorse.
- Create one saved question per card and certify the shared models and metric definitions.
- Add dashboard filters for Date range, model, app or team, environment, provider.
- Exclude test, staging, and playground traffic from headline cards, and show the refresh time.
Example card SQL
WITH daily AS (
SELECT
date_trunc('day', window_start) AS day,
model,
SUM(cost_usd) AS cost_usd
FROM llm_request_rollups
WHERE environment = 'production'
GROUP BY 1, model
)
SELECT
date_trunc('month', day) AS month,
model,
ROUND(SUM(cost_usd), 2) AS cost_usd,
ROUND(
100.0 * (SUM(cost_usd) - LAG(SUM(cost_usd)) OVER (
PARTITION BY model ORDER BY date_trunc('month', day)
)) / NULLIF(LAG(SUM(cost_usd)) OVER (
PARTITION BY model ORDER BY date_trunc('month', day)
), 0), 1
) AS mom_growth_pct
FROM daily
GROUP BY 1, model
ORDER BY 1, cost_usd DESC;