What Is a Span in Distributed Tracing?
Last verified on Nov 8, 2026.
A span is one timed operation inside a trace: an incoming HTTP request, a database query, a call to another service. A trace is the tree of spans for one request. Each span records what ran, how long it took, and whether it worked.
What a Span Contains
OpenTelemetry lists these fields for every span:
- Name of the operation, such as
GET /v1/sys/health - Parent span ID, empty for the root span
- Start and end timestamps, which give the duration
- Span context, an immutable object holding the trace ID, the span's own ID, trace flags, and trace state
- Attributes, key-value metadata about the operation
- Events, timestamped annotations inside the span
- Links, references to causally related spans
- Status, the outcome
OpenTelemetry notes that a span looks like a structured log, and that you can think of a trace as a collection of structured logs with context, correlation, and hierarchy built in. Here is a trimmed, illustrative span for a handler:
{
"name": "POST /checkout",
"context": { "trace_id": "5b8aa5a2d2c872e8321cf37308d69df2", "span_id": "051581bf3cb55c13" },
"parent_id": null,
"start_time": "2026-11-08T18:52:58.114201Z",
"end_time": "2026-11-08T18:52:58.114687Z",
"attributes": { "http.route": "/checkout" },
"status_code": "STATUS_CODE_UNSET"
}A child span carries the same trace_id and sets its parent_id to this span's span_id. That link is how a backend rebuilds the tree. See distributed tracing for how IDs cross service boundaries.
Span Kind
Each span has one of five kinds, a hint to the backend about how to assemble the trace:
If no kind is given, it is assumed to be internal. A server span's parent is often a remote client span, and a consumer span's parent is always a producer.
Span Status
Status has three values: Unset, Error, and Ok. Unset is the default and means the operation completed without an error. Error means something failed, for example an HTTP 500. Ok means a developer explicitly marked the span successful as a final call. OpenTelemetry says you rarely need to set Ok, because Unset already covers success.
Attributes vs Events vs Links
Use an attribute for a fact about the whole operation, such as a user ID or cart ID. Prefer adding attributes when the span is created so they are available to SDK sampling. Use a span event when a specific timestamp is meaningful, such as the moment a page becomes interactive. Use a link when work continues in a different trace, such as a queued job that runs later, and you want to connect the two traces causally.
What Goes Wrong with Spans
- Orphan spans. A span points to a parent that was never exported, often because of sampling or a service without instrumentation.
- Spans that never end. A span with no end timestamp has no duration, so end every span you start, including on error paths.
- Too many spans. Wrapping every function call adds volume and makes traces harder to read. Start with the operations that cross a process boundary.
- Names with IDs in them. The OpenTelemetry API says a span name should identify a class of spans, not one instance.
get_accountis a good name,get_account/42is too specific, and the account ID belongs in an attribute.
Spans in Sazabi
Sazabi, an AI-native observability and security platform, stores each span as a searchable record with its trace and span IDs, name, kind, status, duration, and attributes. Spans with an error status are stored as errors, and each exception a span records becomes its own error record with type, message, and stack trace. Sazabi ingests OpenTelemetry metrics (Prometheus metrics through an OpenTelemetry Collector) and OTLP traces through the same intake as your logs. It stores each metric data point and each span as a log record that its agent queries alongside your logs, so there is no separate metrics store to run. To send spans, follow the OpenTelemetry traces setup, then use latency spikes to see what slow spans look like in practice.
Frequently Asked Questions
What is a span in tracing?
A span is one timed operation in a request, such as an incoming HTTP call or a database query. It has a name, start and end times, and attributes, and many spans together form a trace.
What is the difference between a span and a trace?
A trace is the whole path of one request. Spans are the individual operations inside it, linked by parent-child relationships.
What is a root span?
The first span in a trace. It has no parent span ID and covers the start and end of the whole operation.
What is the difference between a span attribute and a span event?
An attribute is a key-value fact about the whole span. An event is a timestamped point inside the span, so use an event when the moment matters.
Sources
- A span is a unit of work with a name, parent span ID, start and end timestamps, span context, attributes, events, links, and status; span kinds are Client, Server, Internal, Producer, and Consumer; status is Unset, Error, or Ok (accessed Nov 8, 2026)
- The span name SHOULD identify a class of spans rather than individual instances; get_account is good, get_account/42 is too specific, and the ID belongs in an attribute (accessed Nov 8, 2026)
- A span represents a single operation within a trace, and a trace is a DAG of spans with parent-child edges (accessed Nov 8, 2026)
- A span contains a name, time-related data, structured log messages, and attributes about the operation it tracks (accessed Nov 8, 2026)
- The parent-id field is the ID of the caller's request, known as the span-id in some tracing systems, and is 8 bytes (accessed Nov 8, 2026)
- Sazabi stores each span as a record with trace and span IDs, name, kind, status, duration, and attributes; error-status spans are stored as errors and each recorded exception becomes its own error record (accessed Nov 8, 2026)