Does Session Replay Slow Down Your Site? The Real Cost
Yes, session replay adds real, measurable overhead. On a modern browser and a mid-range phone it's usually small enough that your users won't feel it, provided you configure it honestly. Web recorders add roughly 30 to 55 KB gzipped and a single-digit to low-double-digit percent CPU bump while recording. Native mobile replay is heavier per frame, and that's where the cost actually hides. But the number that should worry you isn't the SDK's advertised baseline. It's what happens the moment you tell it to record everything.
I come at this from the privacy side, not the performance side. And the first thing I'll say is that the two problems are the same problem wearing different hats. The setting that makes replay slow (capture the whole DOM, every mutation, every keystroke, unmasked) is the exact setting that walks you over what I keep calling the creepy line. Over-collection is a tax you pay twice: once in milliseconds, once in liability. So when someone asks me whether replay will slow their site down, my honest answer is "it depends entirely on how greedy you told it to be."
Let me give you the numbers, then a recipe so you can stop trusting vendor blog posts (including this one) and measure your own stack.
What the SDK costs before you touch a single setting
The floor cost of a web session replay tool is two things: the bytes it ships to the browser, and the CPU it burns watching the page.
On bytes, the recorders cluster in a fairly narrow band. Sentry got a lot of mileage out of a 35% bundle-size reduction that brought its Replay plugin to roughly 36 KB gzipped, with an aggressive tree-shaken build reaching about 29 KB. In Rollbar's five-script comparison, Fullstory's recorder measured 58.8 KB gzipped against PostHog's 52.4 KB. PostHog is the interesting case here because its 52.4 KB core lazy-loads the replay code only when a recording actually starts, so the number your users pay on first load can be a good deal lower than the number on the tin.
CPU is where the vendors and the independent testers stop agreeing, and it's worth understanding why. Amplitude's docs claim that with default settings, Session Replay uses under 2% of CPU time during normal operation. Meanwhile, Highlight's open benchmark drove rrweb-based recording through real React applications and clocked an average CPU increase around 21% while recording. Those aren't contradictory. A near-idle marketing page barely mutates its DOM, so the MutationObserver has almost nothing to serialize. A busy React app re-renders constantly, and every mutation has to be turned into a replayable diff on the main thread. The cost lives in observation and serialization, not in the network send.
Here's the same picture in one place.
| Web recorder | Added bundle (gzipped) | Reported CPU / main-thread cost | Source |
|---|---|---|---|
| Sentry Replay | ~36 KB (29 KB tree-shaken) | +373 ms Total Blocking Time, +0.24 ms FID on their own UI | Sentry Engineering |
| PostHog | 52.4 KB core, lazy-loaded | "minor" in their own bench; heavier on busy pages | PostHog |
| Fullstory | 58.8 KB | not published in the same test | Rollbar |
| rrweb (via Highlight) | varies by wrapper | ~21% average CPU increase while recording | Highlight.io |
| Amplitude | not published | under 2% CPU on default settings | Amplitude |
The Total Blocking Time figure deserves a flag. Sentry's own engineers, measuring their Replay SDK on an M1 MacBook against a remote backend over 50 iterations, reported a 373 ms increase in Total Blocking Time and a 0.24 ms bump in First Input Delay. TBT isn't a Core Web Vital you rank on directly, but it's the field metric that most closely tracks "the page felt janky while it loaded." A third of a second of extra blocking on fast hardware means noticeably more on a cheap Android device throttled by heat and a slow CPU. Always mentally multiply desktop benchmark numbers by three or four before you decide your mobile users are fine.
Native replay is a different animal
Web replay serializes a document. Native replay, on iOS and Android, mostly takes pictures. That single architectural difference changes the cost profile completely, and it's the part of mobile session replay tooling that trips teams up.
The dominant native approach is periodic screenshotting plus a redaction pass that masks sensitive views before the frame leaves the device. Sentry's mobile SDK captures at most one frame per second, and only when the screen actually changes, which is a sensible default. But the per-frame math is unforgiving. On an iPhone 8, Sentry measured the redaction phase at about 6 ms and the render phase at roughly 25 ms with their newer renderer. A 60 fps display gives each frame a budget of about 16.7 ms. When capture-plus-redaction blows past that budget, the phone drops the frame, and the user sees scroll stutter. On a current flagship you'll never notice. On the four-year-old device your actual users are holding, you might.
So the honest native summary is this: the cadence throttle (one frame per second, skip-if-unchanged) is doing enormous work to keep replay affordable. The cost isn't recording per se. It's redrawing and masking the screen on the main thread more often than the device can absorb. Turn the frame rate up "for smoother playback" without testing on old hardware and you've quietly shipped jank to your least powerful users.
The real cost driver is how much you capture
Strip away the tool-by-tool numbers and one variable dominates all of them: capture volume. On web, that's DOM size times mutation frequency plus any canvas or media you asked it to record. On native, it's frame cadence times screen complexity times how much redaction you're doing. Everything expensive scales with "how much did you tell it to watch."
This is where I put on the privacy hat, because the fix is the same on both sides. GDPR Article 5(1)(c) requires that personal data be "adequate, relevant and limited to what is necessary in relation to the purposes for which they are processed." In plain speech: don't collect what you don't need. That clause was written about privacy, but read it as a performance directive and it still holds. If you mask inputs by default, block the heavy third-party widgets from recording, and sample sessions instead of recording 100% of traffic, you shrink the payload, cut the serialization cost, and stay on the safe side of the creepy line all at once. I have never seen a team regret capturing less.
A worked example from a checkout page I profiled: recording every session, unmasked, with the payment iframe included, produced replay events several times larger than recording a 20% sample with inputs masked and the third-party iframe excluded. The privacy posture went from "storing card-adjacent DOM" to "storing nothing sensitive," and the main-thread cost dropped in the same motion. One change, two wins. If you want the vocabulary for the levers involved, sampling, masking, and blocklists, the behavior analytics glossary covers the terms.
A recipe to profile your own replay overhead
Vendor benchmarks run on the vendor's page. Yours is different. Here's a Core Web Vitals A/B you can run in an afternoon with Chrome DevTools and no special tooling.
- Load your real page (not a demo) in an incognito window with the replay SDK disabled. Open DevTools, go to the Performance panel, enable a 4x CPU throttle and "Slow 4G" to approximate a mid-range phone, and record a cold load plus a scroll and one real interaction. Note LCP, the longest task, and Total Blocking Time.
- Repeat the exact same run with replay enabled at your intended settings. Same throttle, same interactions.
- Diff the two. The delta in TBT and the delta in your worst-interaction INP are your true overhead. If replay adds more than roughly 200 ms of blocking on the throttled profile, your users on cheap hardware will feel it.
- Check the Network tab for the size and frequency of the replay payload. A recorder firing large event batches every few seconds on a data-capped connection is its own problem, separate from CPU.
- Now toggle your capture settings (turn on input masking, add a blocklist for heavy widgets, drop the sample rate) and re-run step 2. Watch how much of the overhead was optional.
That last step is the whole point. Most of what people blame on "session replay being slow" is really "session replay recording far more than it needed to."
Where the tools sit on this
Most modern replay platforms give you the same three dials (sampling, masking, and blocklists) because they all learned the same lesson. Sentry leans on cadence throttling and skip-if-unchanged on native, and publishes its overhead numbers, which I respect. PostHog lazy-loads to protect first paint. Amplitude keeps a low default CPU ceiling. Native-focused tools vary most, because screenshot cadence is the dominant cost and not everyone exposes it clearly.
Kixo belongs in the same conversation: it does web replay through rrweb and native iOS/Android capture, with privacy masking built in, so its cost profile follows the same rules as everything above. The web recorder inherits rrweb's mutation-serialization overhead, and the native path inherits the screenshot-cadence tradeoff. None of these tools escape physics. The differences that matter are how sane the defaults are and how much control you get over capture volume. Pick on that, not on a single benchmark number.
Quick answers
Will session replay hurt my Core Web Vitals? Marginally, if configured well. Expect a small LCP delta and a more noticeable Total Blocking Time bump. Sentry measured about 373 ms of extra TBT on fast hardware, so budget more on throttled mobile. Sampling and lazy-loading blunt most of it.
Does it slow down mobile more than web? Different cost, not simply "more." Native replay's expense is per-frame rendering and redaction on the main thread, capped by a one-frame-per-second cadence. On older phones that cadence is the only thing keeping it smooth.
What's the single most effective thing I can do? Record less. Sample instead of capturing 100%, mask inputs, and blocklist heavy third-party frames. It cuts overhead and keeps you inside data-minimisation rules at the same time.
If you take one thing from this: the SDK's baseline is rarely the villain. Your configuration is. Measure your own page with the recipe above, turn the greedy settings off by default, and revisit them only when a specific investigation needs the detail. Your users' phones, and your compliance posture, will both thank you.