Command recording
For 2D canvases with fewer than about 2,000 draw calls a second: record the drawing commands, replay them exactly. Tiny bandwidth, resolution independent. Image sources are captured once by hash.
A canvas is a bitmap with no DOM inside it. Naive approaches freeze the page and eat memory. Backstory treats each visible canvas as a separately budgeted media stream with three capture strategies and a seven-level quality ladder.
For 2D canvases with fewer than about 2,000 draw calls a second: record the drawing commands, replay them exactly. Tiny bandwidth, resolution independent. Image sources are captured once by hash.
WebCodecs captures a VideoFrame and encodes AV1, VP9, or H.264 in a worker, with keyframes aligned to checkpoints. Unchanged frames are hashed away, so idle dashboards cost nothing.
No readPixels. Frames are captured as VideoFrames inside the same animation frame, or the app calls markFrame when a scene is complete.
| Test | Effect of failing |
|---|---|
| Attached to the document | Scratch canvases created in JavaScript and never appended are ignored |
| Rendered | No display none, visibility hidden, opacity zero, or content-visibility hidden on the canvas or an ancestor |
| Non-zero size | On screen and in the backing store |
| In or near the viewport | Scrolling out pauses; scrolling in captures a keyframe and resumes |
| Page visible | A background tab pauses every canvas |
| Allowlisted or auto-detect | Strict privacy mode requires an explicit allowlist |
When a visible canvas draws a hidden one onto itself, the source bitmap is captured at that moment. The replay shows what the visible canvas showed; the background work stays invisible. OffscreenCanvas in workers has no DOM presence and is never captured.
| Level | Max fps | Resolution scale | Encoder target | Notes |
|---|---|---|---|---|
| L0 Full | 15 | 1.0 (max 1920 px wide) | 800 kbps per canvas | Only when HEALTHY and visible |
| L1 | 8 | 0.75 | 400 kbps | Default for most sessions |
| L2 | 4 | 0.5 | 200 kbps | |
| L3 | 2 | 0.5 | 100 kbps | |
| L4 | 1 | 0.33 | 50 kbps | |
| L5 Interaction-only | keyframe on click, tap, key; else 1 per 10 s | 0.33 | burst only | The accept-loss tier |
| L6 Off | 0 | — | — | Placeholder with a reason |
Free for 1,000 sessions a month. Strict masking, conditional recording, and Signals are all included.
Free for 1,000 sessions a month, no credit card. Or leave a work email and we will reach out about the private beta for healthcare and support teams.
We'll reach out to about the private beta.
We'll email when Backstory opens.