OpenTelemetry Visual Handbook · phase 02 · lab

One request.
How many traces?

A click becomes six services. What makes their spans one trace is a 55-character header. Each service has to read it, continue it and write it again. Watch it travel. Then switch off one proxy's manners and see what the backend receives.

Every id, colour and arrow on the stage is computed from a propagation model. The switches change the model, and the film is rebuilt from it at the same moment.

1 request · 1 trace
Browserweb SDKAPI gatewayinstrumentedcheckoutinstrumentedinventoryinstrumentedlegacy proxyno SDKpaymentsinstrumented

Packet flow

  • first trace
No.StepSourceDestinationProtocolSizeInfo
102browsergatewayHTTP—POST /checkout · traceparent 00-34b62e90a10911c5b658229682045116-9e22945adee533d1-01 · baggage user.tier=gold
203gatewaycheckoutHTTP—POST /orders · traceparent 00-34b62e90a10911c5b658229682045116-47ecbe54d71b412b-01 · baggage user.tier=gold
304checkoutinventoryHTTP—POST /reserve · traceparent 00-34b62e90a10911c5b658229682045116-ed1f3162e5bd2e1f-01 · baggage user.tier=gold
405proxypaymentsHTTP—POST /charge · traceparent 00-34b62e90a10911c5b658229682045116-ed1f3162e5bd2e1f-01 · baggage user.tier=gold
506browsercollectorOTLP—span "click checkout" · trace 34b62e90… · span 9e22945a… · root
606gatewaycollectorOTLP—span "POST /checkout" · trace 34b62e90… · span 47ecbe54… · parent 9e22945a…
706checkoutcollectorOTLP—span "PlaceOrder" · trace 34b62e90… · span ed1f3162… · parent 47ecbe54…
806inventorycollectorOTLP—span "ReserveStock" · trace 34b62e90… · span ed2bbf73… · parent ed1f3162…
906paymentscollectorOTLP—span "Charge" · trace 34b62e90… · span 3fae7ecb… · parent ed1f3162…

Break it, one switch at a time

  1. Play it through once. The trace-id stays the same on every hop. The parent-id changes on every hop. That pair is the entire mechanism.
  2. Turn off “Proxy forwards headers”. Payments receives no traceparent and starts a new root. The backend now holds two traces for one click, and the payments span has lost user.tier.
  3. Turn it back on, and look for the proxy in the trace view. It is not there. A hop without an SDK is invisible, but it can still pass the context on. It does not break the trace unless it drops the headers.
  4. Turn off “Root sampled”. Every span inherits -00. Context still propagates, but no span is exported. Sampling decides what gets recorded, not what gets propagated.

Why “hard” context

Trace context is the minimum needed to join spans: ids and a flag. Baggage is application data that rides on the same hops, such as a tenant or a tier. It is not recorded on spans unless code copies it there. Both survive only where every hop carries them. W3C Trace Context → · W3C Baggage →

The boundary of this experiment

The topology is fixed, and every hop is a synchronous HTTP request. Ids come from a seeded generator, so they repeat between visits. It models traceparent and baggage only. It leaves out tracestate, baggage properties, B3 and Jaeger propagators, messaging links, and span timing. The proxy is a two-state switch. A real proxy can also rewrite, truncate or duplicate headers.

An uninstrumented proxy forwards every header untouched. Does it appear as a span in the trace?

Commit to an answer first. You cannot change it afterwards.