Skip to Content
Rius

How do I track LLM cost per model?

Rius splits LLM cost per model when each model call carries the requested model name and its token counts, and shows the split on the Home page and over MCP. You send the model and usage your instrumentation already records, and Rius prices each call at ingest. You never send a price or a cost.

How it works

Rius prices each LLM span when it arrives, then groups the priced calls by model.

  • The model name. Rius looks up gen_ai.request.model in a price table. A span that carries only gen_ai.response.model is not priced, so make sure the requested model is on the span.
  • The token counts. Rius multiplies each count by its own rate: gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, and the cache counts gen_ai.usage.cache_read.input_tokens and gen_ai.usage.cache_write.input_tokens. Input tokens are read as the total prompt, including cached tokens. The uncached share is that total minus cache reads and writes. Token counts recorded in OpenInference or OpenLLMetry form are normalized at ingest.
  • The prices. They come from LiteLLM’s public model-price catalog, in US dollars. Provider prefixes (openai/gpt-4o), dated snapshots and the Amazon Bedrock and Google Vertex AI spellings resolve to the same price, so one model does not split into several rows.
  • Estimates. Costs are list-price estimates at standard rates. Long-context tiers, batch, flex and priority pricing, and negotiated discounts are not applied, so your invoice can differ.
  • Unpriced models. If a model is not in the catalog, or the span has no token usage, its cost stays empty, not zero. The span keeps its tokens and timings.

Cost is fixed on the span when it is written. A later price change does not rewrite past calls.

Set it up

  1. Send traces from an SDK that records the model and usage on each LLM call. With a global init(), installed integrations are turned on automatically, so a call like this one is traced with its model and token counts. The full install and init steps are in the Quickstart and SDK installation.
import anthropic import rius rius.init(api_key="ri_...", service_name="my-agent") claude = anthropic.Anthropic() # reads ANTHROPIC_API_KEY @rius.observe def handle(query: str) -> str: response = claude.messages.create( model="claude-haiku-4-5-20251001", max_tokens=200, messages=[{"role": "user", "content": query}], ) return response.content[0].text handle("What should I check when a collector drops spans?")
  1. If you instrument by hand or with another OpenTelemetry library, set gen_ai.request.model and the usage attributes above on each model call. Do not send a cost attribute. A cost you send is ignored.
  2. Open Home in the console and pick a window: 15m, 1h, 1d, 7d, 30d or a custom range. The cost-by-model panel and the models table fill in as priced calls arrive.
  3. Check the note on the cost-by-model chart. It says how many LLM calls had their cost resolved, so you can tell a complete split from a partial one.
  4. To ask over MCP, connect the Rius MCP server to your client and ask for cost by model in plain language. For example: “What do planner’s gpt-4o runs cost?”

What you get

  • Cost by model on Home. The cost-by-model chart shows how many LLM calls were priced. The models table lists calls, latency, tokens and cost for each model, with a time to first token p95 per model. Embedding calls are left out of the LLM calls count, but their cost appears in the cost-by-model breakdown. See Usage and cost for the full page.
  • Comparison with the previous period. The stat tiles show total cost with per-trace and per-1k-token averages against the previous window.
  • Single calls. Span detail shows one call’s provider, model, tokens and cost. The Spans tab on the trace list sorts individual calls by cost.
  • Cost by model over MCP. Your client calls workspace_metrics_overview for the workspace total and cost by model. It calls agent_traces_summary for one agent or service, and list_spans and list_agent_traces for the individual calls and runs behind a number.
  • Alerts scoped by model. Cost is a metric in custom alerts, measured per trace, and you can filter a rule by model. A rule over mostly unpriced models can stay quiet, so check which models are priced on the cost-by-model panel first.
  • Honest totals. Totals add up only the priced calls. A console total with nothing priced in it shows a dash, not $0.

When something else fits

  • If your invoice must match to the cent, use your provider’s billing data. Rius shows list-price estimates and does not apply custom prices or negotiated, batch, flex, priority or long-context pricing.
  • If you want a total-spend or budget alert for the whole workspace, watch it on the Home page, because that is not an alert metric today.

Still stuck? Get help

Last updated on