Overview

Syncline records a browser session and the backend trace behind it, then draws them against one clock. The interesting part is not either half — both exist already — but the seam between them, and how it is made reliable.

The problem

Session replay tools show you the browser. Tracing tools show you the backend. When someone reports that checkout was slow, you watch a video, guess a timestamp, and go looking in a second tool whose clock does not agree with the first one. Most of the work is correlation, by hand, under time pressure.

The mechanism

The browser SDK mints a W3C traceparent for every request it is allowed to touch, and writes that trace id into the rrweb stream itself as a custom event, at the frame the request fired. Your backend reads the header with ordinary OpenTelemetry instrumentation and continues the trace. The viewer then resolves player time to a trace id to a span tree.

The consequence worth understanding: the join is by identifier, not by time. Clock skew between a laptop and a server changes where a span is drawn; it can never change which request a span belongs to. Skew is a rendering concern, and it is measured and shown rather than hidden.

The pieces

ComponentWhat it does
syncline-browserRecords with rrweb, patches fetch and XHR, uploads chunks
apps/apiAuthenticates, stores the raw body, enqueues. Parses nothing
apps/workerValidates, normalizes OTLP, writes rows
apps/webThe recordings list and the viewer

Where to go next

Pre-alpha. Recordings are scoped to the organization that owns them and the dashboard requires an account, but there are still no invitations, no roles beyond owner and member, and no retention or deletion. Do not point this at production traffic yet.