Zenaique

Order the lifecycle of one OTel span from start to export

Order steps·Easy·4.0 · 0·~1 min·Asked atNeo4jNetflixObserve Ai
Attempt it
  • 1The Exporter ships the batch to the backend (Langfuse, Phoenix, OTel Collector)
  • 2If the work fails, the app sets span status to ERROR and records the exception
  • 3The SpanProcessor (typically BatchSpanProcessor) buffers the span
  • 4span.end() stamps the end timestamp and hands the span to the SpanProcessor
  • 5Application code sets attributes and records events on the span
  • 6tracer.start_span(name) creates the span and stores it in the active context
TL;DR

Start, enrich with attributes, mark failure if any, end, buffer through the SpanProcessor, export to the backend.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Picture writing a postcard from a trip. First you grab a blank card and write the date on top. As the day unfolds you jot down details: where you went, who you met, what you ate. If anything went wrong (you missed the train) you scribble a note about that too. At the end of the day you stamp the finish time and drop the card into a mailbox at your hotel. The hotel collects all the cards from all the guests, bundles them together overnight, and the postal service trucks them off to wherever they need to go. The postcard is the span. The mailbox is the SpanProcessor. The truck is the Exporter. Once you drop the card in, you cannot edit it any more.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

Understanding the span lifecycle in order is what separates 'I added OTel and traces appear' from 'I can debug why a trace did not appear'. Almost every operational bug in LLM tracing maps to one specific stage of the lifecycle going wrong, and the symptoms differ depending on which stage.

This question puts the six stages on the table. The deeper learning is how the stages interact with async, with short-lived processes, and with the SpanProcessor's batch tuning.

Start: span creation and context

tracer.start_span(name) creates a span object, captures the start timestamp, and assigns it a span id linked to the current trace id (or starts a new trace if no parent context exists). The span is now mutable.

The critical detail is whether the span becomes the active span in the current context. start_span alone does NOT do this; it just creates the object. To make the new span the parent for any subsequent spans, you either use start_as_current_span (a context manager that handles activation and deactivation) or you manually attach it to the context via trace.use_span(span).

The failure mode for getting this wrong is flat traces: every span ends up at the root, none nest, the tree view in your backend looks like a row of bars instead of a hierarchy. This is one of the top two beginner bugs in OTel instrumentation, alongside forgetting to flush at process exit.

Enrich: attributes, events, and links
Mark failure: exception and status
End: freeze and handoff
Buffer and Export: the asynchronous handoff
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.

Real products, models, and research that use this idea.

  • Python opentelemetry-sdk 1.x BatchSpanProcessor with OTLPSpanExporter is the canonical production pairing.
  • Langfuse's OTel ingest endpoint accepts spans exported via OTLP HTTP from BatchSpanProcessor.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QWhat changes about this lifecycle in an async / coroutine context?
A

Talk about context propagation across await points and the contextvars-based active span mechanism.

1 more follow-up an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Trying to set attributes or status after calling span.end(). Once end() runs, the span is frozen and any later mutation is silently dropped.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • Recall the six stages of a span lifecycle in order

  • Place exception recording and status mutation correctly relative to end()

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
Describe how end user thumbs up/down should flow back onto a trace
Flashcard·Easy