Explains OpenTelemetry context propagation including trace context and baggage, W3C and B3 formats, propagators, inject and extract workflows, and composite support for cross service distributed tracing.
Hello, span explorers.This article explains context propagation — a core concept in distributed tracing — and shows how OpenTelemetry moves trace context and baggage across processes and services. Building on span basics (start/end time, events, attributes, span context, and baggage), you’ll learn:
What span context and baggage contain
Why a universal trace format matters
How OpenTelemetry injects and extracts context across carriers
Common propagation formats you will encounter (W3C Trace Context, B3, Composite)
Quick recap — what span context and baggage hold:
Trace ID: ties the entire trace together
Span ID: uniquely identifies a single span
Trace flags: indicates whether the span was sampled
Trace state: vendor-specific data
Baggage is arbitrary key-value metadata that travels with the context (e.g., product ID, cart ID, promo code). This helps services downstream make decisions or add useful attributes to spans.
Trace context contains the tracing identifiers and flags; baggage carries custom key/value metadata. To move both across service boundaries we need a standard wire format.
Why a standard format?Historically, many APM vendors and open-source tools used proprietary HTTP headers for propagation. Non-standard headers are often dropped by middleware, load balancers, or proxies, which breaks distributed traces. To solve these interoperability problems, the W3C Trace Context standard (circa 2018) became the industry default and is the OpenTelemetry default format. W3C Trace Context ensures cross-vendor compatibility so services and tools can read and continue traces reliably.
W3C Trace Context and W3C Baggage are HTTP header formats. The primary headers are traceparent, tracestate, and baggage.Example (illustrative):
baggage: arbitrary key-value pairs that travel with the request
Note: propagation extends beyond HTTP. The same header concepts apply to gRPC metadata, message attributes in queues, and other carriers.When OpenTelemetry is configured and instrumented correctly, propagators automatically inject and extract these headers so traces continue across service boundaries.
Propagation workflowBefore making an outbound call, the current trace context is injected into a carrier (HTTP headers, gRPC metadata, or a message). On the receiving side, the trace context is extracted from that carrier and restored into the receiving process so the trace can continue.
Propagation is simply the serialization and deserialization of the context object. That context contains trace ID, span ID, trace state, trace flags — plus baggage. Most OpenTelemetry instrumentation handles propagation automatically, but custom integrations use the propagators API directly.
Context managementA single process may have multiple spans concurrently (especially in async or multithreaded apps). The context manager tracks the active span and baggage so the correct span ID is injected into outgoing requests. Proper context management is essential to avoid leaking or mis-associating spans.
Propagator API: core concepts
TextMapPropagator: interface that reads/writes context into carriers (key-value maps).
Carrier: the transport medium (HTTP headers, gRPC metadata, message attributes).
Setter/Getter: functions that write/read keys to/from the carrier.
inject: write the current context into an outgoing carrier.
extract: read context from an incoming carrier and restore it to the process.
Pseudocode example:
# Service A (outbound)propagator.inject(context, headers, setter)# Service B (inbound)context = propagator.extract(headers, getter)
TextMapPropagator is transport-agnostic because it operates on generic key-value pairs. It works for HTTP headers, gRPC metadata, messaging attributes, and custom carriers.
The propagator bridges in-process context to out-of-process communication, enabling traces to be stitched across microservices.
API operations summary:
Inject: serialize a context into an outgoing carrier (e.g., HTTP headers).
Extract: deserialize a context from an incoming carrier for continued tracing.
API building blocks:
Carrier: typically a dictionary-like map of headers or metadata.
Setter/Getter: functions for writing/reading the carrier entries.
Global propagator: application-level configuration that defines which propagation formats are used (e.g., W3C, B3, composite).
B3 propagationB3 (from Zipkin) is a simpler, legacy propagation format still used by many systems (including Istio/Envoy). B3 headers include X-B3-TraceId, X-B3-SpanId, X-B3-ParentSpanId (optional), and X-B3-Sampled.
from opentelemetry.propagate import set_global_textmapfrom opentelemetry.propagators.b3 import B3MultiFormatset_global_textmap(B3MultiFormat())
B3 remains useful for backward compatibility with Zipkin-based ecosystems and tools that expect B3 headers.Composite propagatorsOpenTelemetry supports CompositePropagator, which injects and extracts using multiple formats (for example, W3C + B3). This is useful in mixed environments or during migrations.
When injecting, the SDK can write both W3C and B3 headers to outgoing requests. On extraction, it will try multiple propagators until it finds a valid trace context.Composite propagators are useful for:
Supporting multiple vendors that require different formats
Hybrid environments where some services use W3C and others use B3
Migrating formats while preserving backward compatibility
Arbitrary key-value metadata that travels with the trace
user_id=42,region=us-east
X-B3-TraceId
B3 trace identifier
4bf92f3577b34da6a3ce929d0e0e4736
X-B3-SpanId
B3 span identifier
00f067aa0ba902b7
X-B3-Sampled
B3 sampling flag
1
Propagator types
Propagator
Use case
Notes
Trace Context (W3C)
Default in OpenTelemetry
Uses traceparent/tracestate
W3C Baggage
Carry arbitrary metadata
Uses baggage header
B3
Legacy/Zipkin ecosystems
X-B3-* headers
CompositePropagator
Multi-format compatibility
Combines multiple propagators
Custom propagator
Proprietary carriers or unusual transports
Implement TextMapPropagator interface
Other formats and legacy optionsYou may still encounter other propagation formats (Jaeger headers, ot-trace from OpenTracing, OpenCensus binary formats, or vendor-specific headers). However, W3C Trace Context and W3C Baggage are the industry-standard defaults that OpenTelemetry prefers.
Recap — key concepts
Trace ID: unique identifier for a trace
Span ID: unique for a span; used as parent ID for child spans
Context: object that holds trace data (trace ID, span ID, flags, trace state)
Carrier: transport medium for context (HTTP headers, gRPC metadata, messaging attributes)
Inject/Extract: operations for writing/reading context to/from a carrier
TextMapPropagator: API responsible for serializing/deserializing context
Global propagator: config that selects active propagation formats in your application
Final summaryContext is the object that carries trace data (trace ID, span ID, trace flags, optional tracestate). Propagation is the mechanism that serializes and deserializes that context across process or service boundaries. OpenTelemetry defaults to W3C Trace Context and W3C Baggage, but supports other formats (B3, composite, and vendor-specific) via propagators to ensure backward compatibility and smooth migrations.
OpenTelemetry defaults to the W3C Trace Context and W3C Baggage formats. Use composite propagators when you need to support multiple propagation standards simultaneously (for example, during a migration or when integrating with legacy tooling).