Observability model
How spans, traces, sessions, and users fit together into one hierarchy.
A few objects that nest
Observe is built on a small set of objects that nest: a span sits inside a trace, a trace inside a session, and a session belongs to a user. Eval scores attach on top, to a span or a whole trace. Knowing how these relate is the difference between knowing where to look and guessing: every view in Observe, from the trace list to dashboards and alerts, is a different lens on this one hierarchy.
All of it is collected the same way: your app emits spans through the traceAI SDK, which is built on OpenTelemetry, and Observe reads them.
Mental model
The objects form a strict containment hierarchy, and the ID on each span is what reconstructs it. You don’t assemble traces or sessions by hand; shared IDs do that automatically.
flowchart TD accTitle: The Observe object hierarchy accDescr: A user contains sessions, a session contains traces, a trace contains spans, and eval scores attach to spans or traces. U["User · user.id"] --> S["Session · session.id"] S --> T1["Trace · one request"] S --> T2["Trace · one request"] T1 --> SP1["Span · llm call"] T1 --> SP2["Span · tool call"] SP1 --> EV["Eval score"] T1 --> EV2["Eval score"]
Read it bottom-up when debugging (a bad span, up to its trace, its session, its user) and top-down when analyzing (a user’s sessions, down to their traces and the spans inside).
Key terms
| Object | What it is | Identified by | Learn more |
|---|---|---|---|
| Span | One operation — an LLM call, tool call, retrieval, or agent step — with input, output, timing, and cost. | Span ID (+ parent span ID) | Spans |
| Trace | One complete request, made of all the spans that share its trace ID. | Trace ID | Traces |
| Session | A multi-turn conversation — the traces that share a session ID. | session.id | Sessions |
| User | One end user, across all their sessions and traces. | user.id | Users |
| Eval score | A quality score attached to a span or trace. | Attached to span/trace | Trace evals |
| OpenTelemetry | The open standard the spans are emitted in. | — | OpenTelemetry |
| traceAI | The SDK that produces the spans. | — | traceAI SDK |
How it works
Your app emits spans through traceAI (or OpenTelemetry directly). Each span carries a trace ID, so all spans from one request form a single trace. The backend receives them over OTLP (HTTP or gRPC) and stores them by project, and from there every Observe view runs on the same data.
To enrich the hierarchy, attach a session.id and a user.id in code, and every span inside picks them up. See set session and user IDs and add attributes and metadata.
Walking the hierarchy when debugging
The hierarchy is most useful read bottom-up. A typical investigation starts at the smallest object and climbs:
- Start at the span. A customer complained the assistant gave a wrong answer. You open the span that produced it and read its real input and output: the exact prompt and completion, not a paraphrase.
- Climb to the trace. The span alone rarely explains the failure. You move up to its trace and read the other spans in order: the retrieval that fed bad context, the tool call that returned stale data, the agent step that chose the wrong path. The trace is where the request becomes legible.
- Climb to the session. If the request looked fine in isolation but the conversation still went wrong, you open its session and read the earlier turns. Multi-turn problems, like the assistant losing track or contradicting itself, only show up here.
- Climb to the user. If the pattern repeats, you pivot to the user to see whether it is one customer’s data or a systemic issue across everyone.
Because the IDs link each level to the next, every climb is one click, and you never reassemble context by hand. The same path runs top-down for analysis: start at a user, expand their sessions, then traces, then the spans inside.
When to use this model
- Debugging a bad answer: start at the span that produced it, then read the rest of the trace for context
- Analyzing a conversation: open the session to see every turn in order
- Investigating a customer: pivot from a user to all their sessions and traces
- Measuring quality: read eval scores attached at the span or trace level
Common mistakes
- Confusing a span with a trace: a slow trace tells you a request was slow; the span tells you which step was slow. See Spans
- Expecting sessions without a session ID: traces only group into a session if they share a
session.id. Set it in code - Looking for customers you never tagged: per-user views need
user.idon the spans
Keep exploring
Questions & Discussion