What does the gen_ai.usage.input_tokens attribute mean in Rius?
Rius reads gen_ai.usage.input_tokens as the number of prompt tokens a model call used, cached ones included, and uses it with the model name to compute cost. It is an integer set on the span for the model call. Rius also fills it from older OpenInference and OpenLLMetry names, so you can search and filter on this one key. The full list of attributes is in the span attribute reference.
How it works
What the key holds. gen_ai.usage.input_tokens is an int: the prompt tokens of one model call, including tokens served from the prompt cache. Two related keys are subsets of it, not additions to it:
gen_ai.usage.cache_read.input_tokens: prompt tokens read from the cache.gen_ai.usage.cache_write.input_tokens: prompt tokens written to the cache.
The matching gen_ai.usage.output_tokens holds completion tokens, including reasoning ones.
Which spans carry it. It belongs on the span for a model call, next to gen_ai.request.model. Embedding calls are not counted as LLM calls, but their cost still appears in the per-model breakdown and the cost totals. A wrapper span that repeats the usage of the model calls under it does not carry it. That usage is stored under rius.aggregated_usage.input_tokens instead, and Rius never sums it into token totals or cost, so nothing is counted twice.
What Rius computes from it. Rius computes cost on its servers from gen_ai.request.model plus the gen_ai.usage.* counts: input, output, cache read and cache write, each priced at its own rate.
- A span needs the request model and at least one count. A count the span leaves out is read as 0.
- A span with no model, a model the price catalog does not know, or none of the counts gets no cost.
- Cost is a list-price estimate in US dollars, not a billed amount.
Rius also uses input tokens to divide a call’s context across its parts. If the span carries rius.context.sizes, Rius uses that record. Otherwise it estimates the breakdown from the captured messages, gen_ai.system_instructions and tool definitions.
Older names it is read from. Rius normalizes these spellings onto gen_ai.usage.input_tokens when the span arrives:
- OpenInference:
llm.token_count.prompt, withllm.token_count.completionfilling the output count. - OpenLLMetry and Traceloop: the legacy
gen_ai.usage.prompt_tokens, withcompletion_tokensfor output. - Vercel AI SDK v5 and v6: the
ai.usage.*attributes, normalized to the canonical token keys.
A key you send yourself always wins. Normalization fills gaps and never overwrites. The source keys it maps are removed, so search and filter on gen_ai.usage.input_tokens. A filter on llm.token_count.prompt or gen_ai.usage.prompt_tokens matches nothing.
Set it up
You only set this attribute yourself when you send spans without the Rius SDK, such as from a vanilla OpenTelemetry SDK, a collector or another language. The OpenTelemetry guide covers the full setup. For this attribute:
- Set
gen_ai.request.modelon the model-call span. Without a model Rius cannot compute cost. - Set
gen_ai.usage.input_tokensas an integer. Include cached tokens in it. - Set
gen_ai.usage.output_tokensthe same way, counting reasoning tokens in it. - If the provider reports prompt-cache activity, set
gen_ai.usage.cache_read.input_tokensandgen_ai.usage.cache_write.input_tokens. Both are subsets of the input count, so keep each at or below it. - Do not send a cost attribute. Send the tokens and the model name, and Rius prices the call.
- Export over OTLP/HTTP to the ingest endpoint with your API key in the
Authorizationheader:
POST https://ingest.eu.console.rius-glassflow.com/v1/traces
Authorization: Bearer <your API key>
Content-Type: application/x-protobuf- Open the trace in the console and check that the span shows tokens and a cost. A span that shows tokens but no cost usually has a model the price catalog does not know.
If your instrumentation already emits llm.token_count.prompt or the legacy gen_ai.usage.prompt_tokens, you can leave it as it is. Rius moves the value onto gen_ai.usage.input_tokens at ingest. Use the key names exactly as written, because the same list of attributes is shared by the SDKs and the platform. It is an OpenTelemetry GenAI convention key, listed in the registry.
What you get
- Token counts on each model-call span, with cached prompt tokens included in the input count.
- A cost for each call, priced from the model and the input, output, cache read and cache write counts, each at its own rate.
- Cost totals and a per-model breakdown that include embedding calls.
- One key to search and filter on, whichever convention your spans came from.
- Totals that are not inflated, because usage that a wrapper span repeats is stored separately and never summed.
- A breakdown of a call’s input tokens across the parts of its context.
When something else fits
- If a span has no model, or a model the price catalog does not know, it gets tokens but no cost, so check the model name first.
- If you use the Rius SDK or one of its integrations, they emit the span data for you, and you only need this page to understand what you see.
- For the full list of keys and what each does, use the span attribute reference.