# Trace vs span

> A span is one timed operation, such as a model call. A trace is the tree of spans for one request, and in an LLM app it covers one agent run.

Source: https://www.honeyhive.ai/learn/trace-vs-span (updated 2026-11-11)

A span is one timed operation. A trace is the tree of spans that together make up one request. In OpenTelemetry, spans are [the building blocks](https://opentelemetry.io/docs/concepts/signals/traces/) of traces, and every span in a trace carries the same trace ID.

For an LLM application, an agent run is the trace, and each model call, tool call or sub-agent step inside it is a span. The rest of this page covers what lives on each, with the OpenTelemetry terms. For how context travels between services, see [distributed tracing](/learn/distributed-tracing).

## Side by side

| | Trace | Span |
|---|---|---|
| What it is | The "big picture of what happens when a request is made to an application" | "A unit of work or operation" |
| Has its own record | No, it is the set of spans that share a trace ID | Yes: name, parent span ID, start and end time, span context, attributes, events, links, status |
| Identified by | Trace ID | Span ID, plus its trace ID and parent span ID |
| Timing | Read from the root span | Its own start and end time |
| Error state | Read from the spans in it | Its own status: `Unset`, `Error` or `Ok` |
| Structure | A tree of spans | One node, linked to its parent |

The quotes and the span fields come from the OpenTelemetry [traces docs](https://opentelemetry.io/docs/concepts/signals/traces/).

## What a span holds

A span is where the data is. The OpenTelemetry docs list its parts:

- A name, a parent span ID (empty for a root span), and start and end timestamps.
- A span context: an "immutable object on every span" holding the trace ID, span ID, trace flags and trace state.
- Attributes, which are key-value metadata.
- Span events, which the docs compare to "a structured log message (or annotation)" on the span.
- Span links, which "associate one span with one or more spans, implying a causal relationship."
- A status. `Unset` means the span completed without an error, `Error` means an error occurred, and `Ok` means a developer explicitly marked it successful.

Each span also has a kind. Client and server spans cover synchronous remote calls going out and coming in. Internal spans cover operations that do not cross a process boundary. Producer and consumer spans cover jobs created and processed asynchronously, as the [traces docs](https://opentelemetry.io/docs/concepts/signals/traces/) define them.

## How spans form a trace

The span context ties them together. Spans in one trace share the trace ID. A child span records its parent's span ID, so the spans form a hierarchy, and the docs describe child spans as sub-operations. The span with no parent is the root, which [spans](https://opentelemetry.io/docs/concepts/signals/traces/) the whole operation.

Nothing stores a trace as a separate object. It exists because spans point to each other and share an ID. That is why a lost parent link, such as a service that never extracted the incoming context, splits one request into two traces.

## Trace and span for LLM agents

The OpenTelemetry GenAI conventions, marked Development as of November 2026, define span names for agent work. An agent run is an `invoke_agent` span (or `invoke_workflow`) of kind `INTERNAL`, `create_agent` is `CLIENT`, and `plan` is `INTERNAL`. The [agent spans spec](https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/gen-ai-agent-spans.md) gives `chat` and `generate_content` as example operation names for model calls.

The conventions also say how the pieces nest. The LLM call that generates a plan should be a child of the `plan` span, and tool or task spans from that plan are typically siblings under the same `invoke_agent` span. A trace of one agent task is then a tree: the agent span at the root, with plan, model and tool spans beneath it. See [agent tracing](/learn/agent-tracing) for how to build one and [OpenTelemetry for LLMs](/learn/opentelemetry-for-llm) for the conventions in more detail.

The unit you pick matters when you debug. A slow or wrong answer is a trace-level symptom, but the cause sits in a span, because timing and status live there: a model call with a long duration, or a tool call whose status is `Error`. Start at the trace to see the shape of the run, then open the span.

## Trace, session and event in HoneyHive

Some tools use other words. HoneyHive's docs say "a session maps to a trace and an event maps to a span." A session is itself an event with `event_type: "session"` and no parent, and its child events carry the same `session_id`. Child events are [typed](https://docs.honeyhive.ai/v2/tracing/concepts.md) `model`, `tool` or `chain`, and each links to its parent through `parent_id`.

To add your own spans, HoneyHive's [custom spans guide](https://docs.honeyhive.ai/v2/tracing/custom-spans.md) uses the `@trace` decorator, which captures a function's inputs and outputs and nests decorated calls into a hierarchy. For the wider picture of recording and reading agent traces, see [agent observability](/learn/agent-observability).

## FAQ

### What is the difference between a trace and a span?

A span is a single unit of work. A trace is the collection of spans that belong to one request, sharing a trace ID. OpenTelemetry [calls](https://opentelemetry.io/docs/concepts/signals/traces/) spans the building blocks of traces.

### Can a trace have only one span?

Yes. A trace with a single span is just a root span with no children. The root span, in OpenTelemetry's [words](https://opentelemetry.io/docs/concepts/signals/traces/), denotes "the beginning and end of the entire operation."

### Is an LLM call a trace or a span?

A span. The OpenTelemetry GenAI [agent conventions](https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/gen-ai-agent-spans.md) list operation names such as `chat` for model calls and nest the planning model call under a `plan` span, with the plan's tool spans under the same `invoke_agent` span. The agent run is the trace, and each model call is one span in it.

### What is a session in LLM tracing?

It depends on the tool. In HoneyHive, a session is the root of the tree and maps to a trace, and each event maps to a span, per its [tracing concepts](https://docs.honeyhive.ai/v2/tracing/concepts.md).

### Where do errors and latency show up, on the trace or the span?

On the span. Each span [has](https://opentelemetry.io/docs/concepts/signals/traces/) its own start and end time and its own status (`Unset`, `Error` or `Ok`). You read a trace's total time from its root span.
