Skip to content

Trust

What the script costs your page

The recorder runs on your visitors’ devices, so its cost is your cost. These are measurements of the browser SDK 0.4.0, taken from the build on 22 October 2026, not estimates.

31.9 KB
Download, brotli
36.3 KB
Download, gzip
Async
Loads
19 ms
Main thread at load, typical page

Last updated

Download size

Size
Minified105.5 KB
gzip36.3 KB
brotli31.9 KB
Budget (gzip)45 KB

This is ar.min.js, the file the script-tag snippet loads, with the recording engine (rrweb) inside it. The build fails if the gzipped file grows past the budget, so a dependency upgrade cannot quietly make every customer’s site heavier. The player that replays sessions is not in it; only the dashboard loads that.

How it loads

  • The snippet defines a small queue and adds the script with async, so the browser keeps parsing and rendering the page while it downloads. Calls made before it arrives — init, identify, track — wait in the queue and run in order.
  • With requireConsent, the recorder records, stores and sends nothing until consent is given. With sampleRate, a visitor who is not sampled is not recorded at all.
  • Nothing the recorder does may throw into your page: its errors are caught and, with debug: true, written to the console.

What it does on the main thread

  1. Once per page: a snapshot. When recording starts it reads the page once and serialises it, with readable stylesheets as text. This is the largest single piece of work, and it grows with the size of the page.
  2. While the visitor is there: changes. A MutationObserver and event listeners note what changed — elements, text, scrolling, clicks, form input (masked on the device) — instead of reading the page again.
  3. Every 5 seconds: a send. Changes are batched and sent with fetch; when the tab is hidden or closed, what is left goes with keepalive or sendBeacon. Batches are JSON and are not compressed by the recorder.
  4. Not done at all: canvas recording, font collection, screenshots or video.

Measured in Chrome

We loaded a shop page — product cards, a form, a stylesheet — in Chrome 156.0.8078.47, once without the recorder and once with the exact snippet customers paste, 5 times each, and took the median of the difference in main-thread time Chrome itself reports. Then we did the same with the CPU slowed four times, Chrome’s stand-in for a mid-range phone. Ingest was a local stub, so the network is not part of these numbers.

Typical page, 921 elementsHeavy page, 2,721 elements
Added main-thread time while loading19 ms23 ms
… with the CPU slowed 4×75 ms107 ms
Longest single task, 4× slower CPUnone over 50 ms65 ms
Added main-thread time per second of activity7.7 ms4.4 ms
… with the CPU slowed 4×13.1 ms12.9 ms
Long tasks during activity, 4× slower CPU00
Largest upload (the snapshot, uncompressed)165 KB491 KB

“Activity” is 10 seconds in which the page changes twenty elements and scrolls ten times a second — busier than most visits. Chrome counts a task of 50 ms or more as long, because the page cannot answer a tap while it runs. Measured on Apple M4.

Limits worth knowing

A page whose snapshot is larger than 512 KB is not recorded: the recorder stops for that page and says snapshot_too_large in the console with debug: true. On our test page that happens a little past 3,000 elements. See sessions cut short.

  • The snapshot’s cost grows with the page. On the heavy page with a slow CPU it can be a long task; that is the moment to consider sampleRate or ar-block for a large widget nobody needs to see.
  • These are lab numbers from one machine. Your page, your visitors’ devices and other scripts on the page will move them, in either direction.

Watch any session in your language.

Install in minutes, keep the Free plan for as long as you like. One project and 500 sessions a month, free.