Session Replay: What It Is, How It Works, and When You Need It
Session Replay: What It Is, How It Works, and When You Need It
March 16, 2026 (4 days ago)
Written by David Viejo
Last updated March 16, 2026 (4 days ago)
Session replay records what users actually do on your site: mouse movements, clicks, scrolls, keypresses, and every DOM mutation. Play it back and you're watching a user's experience as they lived it.
It sounds invasive. It kind of is. That tension is worth understanding before you pick a tool.
TL;DR: Almost every session replay tool (FullStory, Hotjar, LogRocket, Clarity) is built on rrweb, an open-source library that records DOM mutations as compact diffs. A 5-minute session compresses to 100-500KB. The privacy risk is real: rrweb captures form fields by default. Self-hosting replay keeps data on your infrastructure and costs roughly $5-6/mo in storage at 100K sessions/month.
How Session Replay Actually Works
Almost every session replay tool in existence — FullStory, Hotjar, LogRocket, PostHog Replay, Microsoft Clarity, and most self-hosted options — is built on the same foundation: rrweb.
rrweb (record and replay the web) is an open-source library that works in two steps. First, it takes a full snapshot of the DOM at the start of a session. Then it records every subsequent mutation as a compact, serialized diff. Scroll positions, CSS changes, added or removed elements — every change gets timestamped and appended to the recording stream.
On replay, rrweb reconstructs the DOM from the initial snapshot and replays the mutations in order, synced to a virtual timeline. What you see isn't a video file. It's a reconstructed DOM — which is why replays can be paused, scrubbed, and inspected as live HTML.
The practical implications of this architecture matter:
Storage is small. A typical 5-minute session compresses to 100-500KB. Much cheaper to store than video.
What gets captured is everything rendered. rrweb captures the full DOM, which means user-visible text, form fields, error messages, and anything else on the page. Including sensitive content that you didn't intend to capture.
Network requests are captured separately. Most tools also let you record XHR/fetch requests alongside the DOM replay, which helps correlate user actions with API calls.
The Privacy Problem Is Real
In 2017, Princeton researchers found that session replay scripts on popular sites were capturing credit card numbers and passwords in plain text. The mechanism was simple: rrweb captures form field values by default. If your input isn't masked, the content gets recorded.
Most tools have added automatic masking heuristics since then — detecting fields with type="password", matching patterns for card numbers, etc. But the fundamental issue remains: you're serializing the entire rendered DOM and shipping it somewhere. Unless you explicitly audit what gets captured, you can leak sensitive data.
The tooling has three approaches to this:
Input masking: Replace field values with placeholder characters (*****). All major tools support this. It's on by default for password fields; for other sensitive fields, you have to configure it.
Element exclusion: Mark elements with a CSS class (often rr-block or similar) to exclude them from recording entirely. The element is still visible in the replay as a gray box but its content isn't captured.
Text masking: Replace all text content with x characters. The highest-privacy option, but makes replays harder to use.
The data-transfer issue is separate from what gets captured. When you use a SaaS replay tool, the serialized DOM snapshots — including any content you didn't mask — leave your infrastructure. Under GDPR, this likely constitutes a transfer of personal data, which requires a Data Processing Agreement with the vendor and, if you have EU users and the vendor is US-based, Standard Contractual Clauses.
The Tools Compared
FullStory — The enterprise option. Deep session data, rage-click detection, DX Data analytics, and an API for programmatic access. Pricing starts around $300/mo for 1,000 sessions and climbs steeply at volume. Data lives on FullStory's US servers.
Hotjar — The mid-market option. $39/mo for 100 recorded sessions per day (about 3,000/mo). Adds heatmaps and user surveys. Simpler interface than FullStory.
LogRocket — Developer-focused. In addition to session replay, it captures Redux state, network requests, and console logs. Particularly useful for debugging — you get the full application context, not just the visual replay. Pricing starts around $99/mo.
PostHog Replay — Part of PostHog's broader product analytics platform. If you're already using PostHog for event analytics, the session replay is included (up to 5,000 recordings/mo on the free tier). Built on rrweb, same as the others. Self-hostable.
Microsoft Clarity — Free. No session limits. Surprisingly capable: session replay, heatmaps, rage-click detection. The catch is that data goes to Microsoft. Clarity's terms allow Microsoft to "use the data for Microsoft's business purposes." For non-critical sites where data residency isn't a concern, it's compelling given the price.
Self-hosted with rrweb — You can use rrweb directly, record sessions to your own infrastructure, and build a replay UI on top of it. This is what tools like OpenReplay and Highlight.io do, and what some teams build in-house. OpenReplay is fully open-source and deployable with Docker Compose. You own the data. The tradeoff is operational overhead.
When Do You Actually Need Session Replay?
Not every app needs it. Session replay adds a non-trivial script to your page (usually 50-100KB) and generates storage costs. Worth it in these situations:
High checkout or conversion funnel abandonment. "12% of users drop off at step 3" is an analytics fact. Why they drop off requires watching them.
Vague bug reports. "It just doesn't work" tells you nothing. A session replay of that user shows you exactly what they clicked and what the page showed in response.
Onboarding confusion. Where do new users get stuck? Watching 20 onboarding sessions tells you more than most quantitative analyses.
Accessibility issues. Keyboard-only navigation problems, tab order issues, and focus traps show up clearly in replays in ways that automated tests miss.
Less useful for high-traffic content sites where most pages are informational and user behavior is predictable. More useful for apps with complex workflows, multi-step forms, or frequent user-reported "broken" experiences.
Storage Cost Math
If you're self-hosting, the storage math matters. At 200KB average per session (after compression), 10,000 sessions/month is 2GB. 100,000 sessions/month is 20GB. A year of sessions at that volume is 240GB — about $5-6/mo on object storage.
For most teams, storage cost for self-hosted replay is negligible compared to SaaS pricing. The main operational cost is running the service and maintaining the replay infrastructure. Tools like OpenReplay abstract that away; raw rrweb requires you to build it.
The question to ask: does the debugging and UX value of replay justify the cost (money, storage, operational overhead, and privacy audit work) at your current traffic level? For most teams under 1,000 sessions/day, the answer is yes if you're running a complex product. For simple sites, probably not.
If you want to add self-hosted session replay to your app, we wrote a step-by-step guide: how to add session replay without FullStory or Hotjar. For the broader observability picture, see how to set up error tracking without Sentry and building an uptime monitoring system.