tezvyn:

Span: The Building Block of a Distributed Trace

AI-drafted, machine-checkedSource: github.comintermediate

A Span is a single unit of work in a request's journey, like one leg of a flight. Spans capture the duration and context of individual operations (e.g., a DB query), helping you debug latency in distributed systems.

WHY IT EXISTS To debug modern, distributed systems, you can't just look at one server's logs. You need to follow a single request as it jumps between services. A Span was created to be the fundamental unit of observation for this journey, capturing 'what happened' and 'how long it took' for one specific step.

THE MENTAL MODEL Think of a Span as a single entry in a travel diary for a request. It records the start time, end time, and important details of one specific activity, like 'database query' or 'external API call'. A collection of these diary entries, linked together by parent-child relationships, forms the complete story of the request's journey, which is called a Trace.

HOW IT WORKS An OpenTelemetry Tracer object creates a Span. Each Span is assigned a unique SpanId and inherits a TraceId from its parent (or starts a new one). It contains a start timestamp, a name, and can be enriched with key-value pairs called Attributes (e.g., db.statement: "SELECT *") and timestamped Events (e.g., 'cache miss'). When the operation finishes, you call End() on the Span, which records its end time and marks it as complete.

WHEN TO USE IT Use Spans to instrument any distinct, time-bound operation within your application. This is essential for functions making network calls (to databases, caches, or other microservices), significant in-process computations, or any piece of code whose performance you want to isolate and measure as part of a larger request flow.

WHEN NOT TO USE IT Don't create Spans for trivial, synchronous, in-memory operations that are extremely fast (nanoseconds) and have no I/O. Over-instrumenting with too many fine-grained Spans can add performance overhead and create noisy, hard-to-read traces. A Span should represent a meaningful unit of work, not every function call.

ONE CANONICAL EXAMPLE A web server receives a request and starts a 'parent' Span named /users/:id. Inside that handler, it makes a database call. It creates a 'child' Span named db.query. This child span inherits the TraceId from the parent but gets its own SpanId. When the database call finishes, the child span is ended. When the HTTP response is sent, the parent span is ended. This creates a two-level trace showing total request time and how much of it was spent in the database.

Read the original → github.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.