Operations
Cost accounting
ai_usage_record is the billing-grade record: one append-only row per model call, written off
the request path, with the cost computed at write time.
The row
| Column | Meaning |
|---|---|
organization_id | The tenant that spent it |
location_id | The scope, when the turn had one |
user_id | The acting user. 0 when unattributed |
surface | Which path spent it — chat, agent, embeddings |
model | The model actually used |
prompt_tokens | Input tokens, as the provider reported |
completion_tokens | Output tokens, including reasoning tokens |
total_tokens | The sum of the two above |
cached_input_tokens | Cache reads. On a warm turn, almost all of the input |
cache_write_tokens | Cache writes. Billed above ordinary input on some models |
reasoning_tokens | Telemetry only. Already inside completion_tokens |
estimated_cost_usd | numeric(12,6), computed at write time |
request_id | Correlates with the telemetry row |
created_at | UTC |
One turn can write several rows: each model call is its own row, and a turn that loops over tools calls the model more than once.
Queries worth having
Spend by tenant, this month.
SELECT organization_id,
SUM(estimated_cost_usd) AS usd,
SUM(total_tokens) AS tokens,
COUNT(*) AS calls
FROM ai_usage_record
WHERE created_at >= date_trunc('month', now() AT TIME ZONE 'utc')
GROUP BY organization_id
ORDER BY usd DESC;
Daily trend, one tenant.
SELECT date_trunc('day', created_at) AS day,
SUM(estimated_cost_usd) AS usd
FROM ai_usage_record
WHERE organization_id = 42
AND created_at >= now() - interval '30 days'
GROUP BY 1
ORDER BY 1;
Cache effectiveness. Cache reads are an order of magnitude cheaper than ordinary input, so this ratio is the single biggest lever on unit cost.
SELECT model,
SUM(cached_input_tokens)::numeric / NULLIF(SUM(prompt_tokens), 0) AS cached_share,
SUM(cache_write_tokens)::numeric / NULLIF(SUM(prompt_tokens), 0) AS write_share
FROM ai_usage_record
WHERE created_at >= now() - interval '7 days'
GROUP BY model;
Reasoning share of output. If this is high, the output ceiling is doing more work than you think — see Plans and ceilings.
SELECT model,
SUM(reasoning_tokens)::numeric / NULLIF(SUM(completion_tokens), 0) AS reasoning_share
FROM ai_usage_record
WHERE created_at >= now() - interval '7 days'
GROUP BY model;
Cost per turn, using the request id to collapse a turn's calls:
SELECT request_id, SUM(estimated_cost_usd) AS usd, COUNT(*) AS calls
FROM ai_usage_record
WHERE organization_id = 42 AND created_at >= now() - interval '1 day'
GROUP BY request_id
ORDER BY usd DESC
LIMIT 20;
That last one is the query to run when a customer asks why their bill moved. The expensive turns are rarely the ones anyone expected.
Two ways the numbers lean high
The practical consequence: a new model or a provider that stops reporting breakdowns makes
month-to-date spend jump without anything actually costing more. Check
cached_input_tokens = 0 AND cache_write_tokens = 0 before believing a spike.
SELECT model,
COUNT(*) FILTER (WHERE cached_input_tokens = 0 AND cache_write_tokens = 0) AS no_breakdown,
COUNT(*) AS calls
FROM ai_usage_record
WHERE created_at >= now() - interval '1 day'
GROUP BY model;
Reconciling with the provider invoice
Expect Tether's total to be at or above the invoice. Sources of drift, in order of size:
- Calls with no reported token breakdown, priced at the worst rate.
- A model matched by prefix to a family whose rates have since changed.
- Rounding — each row is rounded to six decimal places.
- Provider-side discounts, batch rates and regional pricing, none of which the table models.
If Tether's total is below the invoice, something is wrong. That is the direction the pricing table is built to make impossible, so treat it as a missing price entry rather than a rounding artefact.
Ledger versus telemetry
Both record cost, at different grains and for different purposes:
ai_usage_record | ai_request_telemetry | |
|---|---|---|
| Grain | One model call | One request |
| Written | Durably, with retries | Best-effort, loss-tolerant |
| Read by | The budget breaker | Humans and dashboards |
| Use for | Billing, caps, reconciliation | Debugging, latency, routing |
Bill from the ledger. Investigate with telemetry.