Skip to main content
Durable workflows can pause for minutes or days, resume in another process, and retry one step several times. Do not keep one span open for the complete workflow lifetime. Long spans are difficult to flush, can be lost when a process stops, and do not describe retries clearly. Use finite spans for active work, stable workflow attributes for search, and span links when work resumes from an earlier execution context. Create one trace for each active execution attempt or short execution burst. Record these attributes on its root span and important child spans: These are Squasher conventions for custom OpenTelemetry attributes. Do not put credentials, full payloads, or customer content in them. Use a low-cardinality value for squasher.workflow.id and squasher.workflow.step. Use run_id and checkpoint_id only for direct search, not dashboard grouping. Use a parent-child relationship when work continues in one live causal call and you can propagate the normal trace context. Use a span link when:
  • a retry starts after the earlier process or trace ended
  • a checkpoint resumes in a new runtime instance
  • one step combines several messages or upstream runs
  • one completed step starts several independent branches
A span has one parent but can have several links. Squasher preserves OTLP span links and shows them in the span Links tab.

Retry example

The first attempt can end with an error. The next attempt starts a new trace and links its root span to the failed attempt:
Use your OpenTelemetry SDK’s normal context and link types. The exact constructor names can differ by language.

Checkpoints and state changes

Record a span event when a checkpoint occurs during an active span:
If no span is active, emit a structured log with the workflow run, step, and checkpoint attributes. Link the next execution span to the last stored span context when it is safe and available. Do not create a fake parent when the earlier context is missing. Stable workflow attributes still let you find the related attempts.

Status and errors

  • End each attempt span when that attempt stops running.
  • Set span status to ERROR when an attempt fails.
  • Record error.type and a safe error message.
  • Record the final workflow outcome as a structured event or finite completion span.
  • Keep timeout, cancellation, retry, and terminal failure as different outcomes.

Verify

  1. Run one workflow that pauses and resumes.
  2. Run one workflow that fails once and then succeeds.
  3. Search by squasher.workflow.run_id and confirm every attempt appears.
  4. Open the retry span and confirm its link opens the earlier attempt.
  5. Confirm that no span remains open only because the workflow is waiting.

References

Agent handoff