Skip to main content
Durable workflows can pause for days, resume in another process, and retry a step many times. Model each active attempt as a finite span, and link resumed work to the earlier attempt, instead of one span that stays open for the full workflow.

Prerequisites

  • A service that sends traces to Squasher with an OpenTelemetry SDK. See OpenTelemetry.

Name the workflow on each span

Put these attributes on the root span of each attempt and on important child spans: These names are a convention. Squasher stores them as ordinary span attributes and gives them no special meaning. Do not put credentials, full payloads, or customer content in them. Use a parent span when work continues in one live call. Use a span link when a retry starts after the earlier trace ended, when a checkpoint resumes in a new process, or when one step starts several branches.
previousAttemptSpanContext is the span context that you stored with the earlier attempt. If you did not store it, do not invent a parent: the workflow attributes still connect the attempts.

Record checkpoints and outcomes

  • Record a checkpoint during an active span as an event: span.addEvent("workflow.checkpoint", { "squasher.workflow.checkpoint_id": checkpointId }).
  • End each attempt span when the attempt stops, not when the workflow ends.
  • Set the span status to ERROR when an attempt fails. That creates an issue in Squasher.
  • Record error.type on the failed span. Squasher uses it to group the issues.
  • Record the final outcome as an event or a short completion span.

Verify

  1. Run one workflow that pauses and resumes, and one that fails once and then succeeds.
  2. In Squasher, select Traces in the sidebar.
  3. Open the retry span. Its Links tab shows the earlier attempt, and its Attributes tab shows the workflow attributes.
  4. Select Issues in the sidebar. The failed attempt is an issue.

Next steps

Tail sampling

Keep error and slow traces and drop routine ones.

Design queryable logs

Choose fields that stay easy to search.