Skip to main content

What is a Trace?

A trace represents a single logical operation or flow in your application. It’s the fundamental unit of data in the Mirador platform. Traces capture:
  • The operation name
  • Attributes (key-value metadata)
  • Tags (categorical labels)
  • Events (timestamped milestones)
  • Transaction hints (blockchain correlation)

Creating a Trace

Create a trace using the client.trace() method:

Trace Options

Web SDK:
Node.js SDK:

Trace Lifecycle

1

Create

Call client.trace() to create a new trace builder
2

Build

Add attributes, tags, events, and transaction hints using the fluent API
3

Flush

First flush sends FlushTrace to the gateway
4

Update

Subsequent flushes send FlushTrace with new data

Keep-Alive & Closing Traces

The SDK sends periodic keep-alive pings to the server to maintain trace liveness. The ping interval is configurable at the client level:

Smart Defaults

The autoKeepAlive option controls whether the keep-alive timer starts automatically when a trace is created:
  • New traces (autoKeepAlive defaults to true): the timer starts automatically after the first flush.
  • Resumed traces (when traceId is set, autoKeepAlive defaults to false): the timer does not start automatically.
This prevents zombie keep-alive timers — for example, when a backend resumes a frontend trace just to append a few events and close it, there’s no need for the backend to keep pinging.

Manual Control

You can manually start or stop the keep-alive timer at any time using the startKeepAlive() and stopKeepAlive() methods on the trace. Both methods are idempotent — calling them multiple times is safe.

Resilience

The keep-alive timer is resilient to transient network issues:
  • An in-flight guard prevents overlapping pings if a previous ping hasn’t completed yet.
  • On failure, the SDK performs a single retry before counting the attempt as failed.
  • After 3 consecutive failures, the timer automatically stops to avoid wasting resources.

Max Trace Lifetime

You can bound the maximum lifetime of a trace independently of keep-alive using the maxTraceLifetimeMs client option. When the lifetime is exceeded, the trace is automatically closed.
maxTraceLifetimeMs defaults to 0 (disabled). When set, it applies to all traces created by the client.

Closing Traces

Always close traces when you’re done to clean up resources:
Enable auto-close on page unload for browser applications:

The Builder Pattern

The Trace class uses a fluent builder pattern. All methods return this, allowing you to chain calls:

Getting the Trace ID

In v2, the trace ID is generated client-side at creation time and is available immediately via getTraceId():

Client-Side Trace ID Generation

In v2, trace IDs are generated client-side at creation time as W3C Tracing Context compatible 32-character hex strings. The ID is available immediately via getTraceId() — no need to wait for the server response.
This is especially important for cross-SDK trace sharing — the frontend can generate the ID and pass it to the backend via headers before any network call completes.

Flushing

Both the Web SDK and Node.js SDK automatically batch and send trace data at the end of the current JavaScript tick (microtask). All flushes send idempotent FlushTrace requests. You can also call flush() manually at any time to send pending data immediately:
flush() is fire-and-forget — it returns void and maintains strict ordering of requests internally.

Cross-SDK Trace Sharing

You can share a trace between the frontend (Web SDK) and backend (Node.js SDK) so that both sides contribute data to the same trace. This is useful when a user action in the browser triggers a backend API call that you want to correlate.

How It Works

  1. The frontend creates a trace — the ID is available immediately via getTraceId()
  2. The trace ID is passed to the backend (e.g., via an HTTP header) before any network call completes
  3. The backend resumes the trace by passing traceId in TraceOptions

Frontend (Web SDK)

Backend (Node.js SDK)

Backend → Frontend

You can also create a trace on the backend and resume it on the frontend:

Best Practices

Name Traces Descriptively

Use clear, action-oriented names:

One Trace Per Logical Operation

Create a new trace for each distinct user action or flow:

Include Context Early

Add identifying attributes at trace creation:

Next Steps

Events

Add timestamped events to traces

Attributes & Tags

Enrich traces with metadata