Skip to content

A span event is one timed operation — a request, a render, a database call — inside a trace. Spans point at their parent span, which is how the trace waterfall is built. Spans are also how metrics travel: there's no separate metric event, and no separate trace event either.

Where it comes from ​

  • span(name, fn) / asyncSpan(name, fn) — sent when fn returns, throws, or its promise settles.
  • startInactiveSpan(name) — sent when you call end().
  • Integrations that time things automatically (e.g. outgoing HTTP requests).

See Tracing and Metrics.

Payload ​

json
{
    "type": "span",
    "timestamp": "2026-09-24T10:15:02.913Z",
    "tags": {},
    "contexts": { "environment": "production", "http.method": "GET", "http.status_code": 200 },
    "payload": {
        "uuid": "c1d9…",
        "name": "GET /api/cart",
        "traceId": "5b7c0e1a-…",
        "parentId": "8a2f…",
        "startTime": "2026-09-24T10:15:02.481Z",
        "endTime": "2026-09-24T10:15:02.913Z",
        "duration": 432,
        "op": "http.client",
        "status": "ok",
        "metrics": { "cart.items": 3, "response.bytes": 5120 }
    }
}
FieldTypeDescription
uuidstringThis span's id.
namestringWhat was timed — the first argument to span().
traceIdstringThe trace this span belongs to.
parentIdstring, optionalThe enclosing span's id. Absent on a trace's root span.
startTimestringISO 8601 start time.
endTimestringISO 8601 end time.
durationnumberDuration in milliseconds.
opstring, optionalOperation category (http.client, db, ui.render, …) from { op } in the span's options.
statusok | error | cancellederror when the callback threw or its promise rejected, otherwise ok, unless changed with span.setStatus().
metricsobjectname → number values recorded with span.metric(name, value).

Values set with span.setData(key, value) aren't part of the payload — they're merged into the event's contexts.

Traces ​

A trace isn't an event of its own: it's the traceId its spans share. The first span that arrives with a new traceId creates the trace on the project's Traces page, and every later span with the same id joins it.

The trace's environment, user, tags and contexts come from its root spans (no parentId) — until one arrives, from the earliest span seen. In the browser one page trace can have several roots (a click that fires a request after the pageload span ended); each merges its tags and contexts into the trace instead of replacing them.

Trace-level contexts ride on the root span. browserTracingIntegration puts previous_trace.id — the trace of the page the user came from — on the pageload/navigation span, and the dashboard links the page traces of one visit through it (see Walking a visit).

Metrics ​

Every span.metric(name, value) call inside a span lands in its metrics map. Calling it twice with the same name keeps only the last value. Metrics are charted on the project's Metrics page and are always tied to the span (and trace) they were recorded in.

Sampling ​

The SDK's tracesSampleRate is decided per traceId, not per span: every span of a trace is either sent or dropped together, so you never see a half-sampled waterfall. Errors and logs from an unsampled trace are still sent and still carry its trace.id.

Quota ​

Counts as one toward the monthly spans limit — the only limit tracing is billed by, since a trace isn't an event of its own. The values in metrics cost nothing of their own.