Skip to content
TraceItX Docs
Documentation

Session replay

A short replay of what actually happened, captured from what the app rendered — not a screen recording.

Updated

The SDK keeps a rolling window of what the app rendered in memory. When a report is filed that window is frozen and attached; the rest is discarded. Nothing is uploaded unless someone files a report, and there is no MediaProjection permission prompt — this is not screen recording.

Turning it on

Server-gated — enable it for the app in the dashboard, and the SDK picks it up from GET /api/config on the next start.

There is no client-side switch for replay on Android — the server gate is the only control. If you need it off for a particular build, turn it off for that app in the dashboard.

Format

Android replays are traceitx-vtree-v1 — a frame timeline, not video. A viewport, a list of frames, and per-frame operations on a lightweight node tree carrying role, frame, text, bg, alpha, cornerRadius and masked.

That keeps a replay in the tens of kilobytes rather than the megabytes video costs, and it means text stays text — searchable, and redactable before it leaves the device. No video encoder runs, which is the difference between a buffer you can leave on and one you cannot, especially on low-end hardware.

Both Compose and classic View hierarchies are captured; the recorder works on the rendered tree, not on your composables.

Images

Image bytes are optional and content-addressed, keyed by the first 16 hex characters of their sha256, so the same drawable across many frames costs one entry. The server’s asset mode (off, bundled, all) decides whether they travel; see Server config.

An unresolved image renders as a placeholder box rather than failing the replay.

Privacy

Sensitive views — Modifier.txSensitive(), TXSensitiveView, markSensitive() and password fields — become a single node with masked: true and no text; the subtree beneath is dropped. The masking happens in the producer, before the frame is written — masked content never exists in the buffer. See Sensitive content.

Compose text is captured: the text of a Text composable lands in the node, redacted. The contents of text fields are never read, so what a user types is not in the replay unless another composable displays it.

Cost

Frames are captured on the choreographer’s cadence and diffed, so a static screen costs almost nothing. replayDurationSec bounds the window; samplingRate decides what fraction of sessions allocate a buffer at all.