Concepts
The Rius data model in one page: what a trace is, what spans and generations are made of, and which parts the platform computes for you.
Traces
A trace is one end-to-end agent run. It begins when your agent starts handling a piece of work (a request, a job, a conversation turn) and ends when that work is done. Everything the run did along the way lives inside the trace, so the trace list is effectively a list of agent runs.
Every trace has exactly one root span. The root’s name, duration, and
status are what run-level views show: a failed root means a failed run, the
root’s duration is the run’s latency. Traces belong to exactly one
workspace, determined by the API key they were sent
with, and are grouped by the service.name your SDK or exporter sets.
Spans
A span is one step inside a run: a tool call, a retrieval, a chain stage, an LLM call. Spans nest the standard OpenTelemetry way (parent context), which is what produces the waterfall. Each span carries a kind that classifies it in trace views and per-kind analytics:
| Kind | Meaning |
|---|---|
AGENT | An agent invocation or run |
LLM | A model call (generations use this) |
TOOL | A tool execution |
RETRIEVER | A retrieval or search step |
EMBEDDING | An embedding computation |
CHAIN | A generic processing step (the default) |
On the wire the kind is the openinference.span.kind attribute, set for you
by the SDK’s kind= arguments and by auto-instrumentation. Exceptions are
recorded as standard OpenTelemetry span events and give the span ERROR
status; the waterfall highlights the path from the root to the failing span.
Generations
A generation is an LLM span with model semantics: the requested and
response model, the provider, token usage, request parameters, finish
reasons, and optionally the input and output messages. On the wire these are
OpenTelemetry GenAI (gen_ai.*) attributes; in the console they power the
span’s Model section and the model analytics.
For streamed calls, a generation can carry a gen_ai.first_token span
event marking the moment the first chunk arrived. Time to first token is
derived from it, which is the latency number streaming users actually feel.
Content and metadata
Span data splits into two families with different privacy treatment:
- Content: prompts, completions, tool arguments and results
(
gen_ai.input.messages,gen_ai.output.messages,input.value,output.value). Content is what the Input / Output tab renders, and it is what the SDK’s privacy controls strip or mask at export time. - Metadata: everything else, including names, timings, kinds, models, token counts, and statuses. Metadata always flows, so a span with stripped content still gets full timing, token, and cost analytics.
Computed server-side
Two things you never send because the platform derives them:
- Cost is computed from
gen_ai.request.modelplus the twogen_ai.usage.*token counts, using model pricing maintained server-side. Send token usage, never cost; your instrumentation stays free of pricing tables. - Time to first token is derived from the
gen_ai.first_tokenevent’s timestamp minus the span start.
Convention-native by design
The model above is not a proprietary schema. Rius reads established OpenTelemetry conventions directly (OTel GenAI for generations, OpenInference for span kinds and generic I/O), so traces from third-party instrumentation land with the same analytics as SDK-emitted ones. The span attribute reference is the full wire contract.
Next steps
- Tracing your code: the
@observedecorator, spans, and generations in the SDK. - Span attribute reference: every attribute the platform reads, for sending without the SDK.
- Viewing traces: the trace list, waterfall, and span detail in the console.