Session Replay for QA: rrweb, PostHog, and FullStory Compared

Written By  Crosscheck Team

Content Team

May 21, 2026 9 minutes

Session Replay for QA: rrweb, PostHog, and FullStory Compared

Session replay for QA: rrweb, PostHog, and FullStory compared

A support ticket says "the Continue button does nothing". You open staging, click Continue ten times, and it works every time. Then you watch that user's session replay and see it in four seconds: a cookie banner is sitting invisibly on top of the button, swallowing every click.

Session replay is a recording of what happened in a user's browser. It turns "I can't reproduce it" into "I watched it happen".

Short version

  • Session replay records the page as a stream of DOM changes, not as a video file.
  • rrweb is the open source library that PostHog and many other tools build on.
  • PostHog gives you replay next to product analytics; FullStory gives you replay next to search and funnels.
  • Privacy masking, retention length, and pricing model differ more than the playback features do.
  • Replay shows the browser only. It cannot show server state, database rows, or the text inside masked fields.

What session replay actually records

Most replay tools do not record your screen. They record the DOM, which is the browser's live structure of the page.

The recorder takes one full snapshot of the page when the session starts. After that it records only the changes: a class was added, a text node changed, an element was removed. It also records mouse movements, clicks, scrolls, key presses, and page navigations.

Playback rebuilds the page from those changes and replays them on a timeline. That is why replay files are small compared to video, and why you can usually select text inside a replay.

This design has one consequence that matters for QA. Anything that never touched the DOM was never recorded.

The three tools at a glance

rrwebPostHogFullStory
What it isOpen source recording libraryProduct analytics suite with replayExperience analytics suite with replay
Who runs itYouCloud or self-hostedVendor cloud only
Setup effortHigh. You build storage and a playerLow. Add the SDK, turn replay onLow. Add the script
Default privacyRecords everything except password inputsMasks all text inputs by defaultMasks input values by default, with rules
RetentionWhatever your storage allowsFixed windows by planFixed windows by plan
Pricing modelFree code, you pay for storagePer recording capturedPer session or seat, quoted
Best forCustom needs and strict data rulesTeams already using PostHog eventsLarger teams with support and CX users

rrweb: the open source engine

rrweb is a JavaScript library that records and replays DOM changes. It is free and it is the foundation many commercial tools use, including PostHog.

You get the recorder and the player. You do not get storage, search, user identification, or access control. You build those.

Pick rrweb when your data cannot leave your own servers, or when you need to record something unusual, such as an internal admin tool with no seats to buy. Expect real engineering work: a session can produce megabytes of events, and someone has to own that pipeline.

PostHog: replay next to your events

PostHog is a product analytics tool that also records sessions using rrweb under the hood. Its strength for QA is the link between events and video.

If you track an event called checkout_failed, you can filter to sessions that fired it and watch only those. You can jump straight to the moment the event fired instead of scrubbing a twenty-minute session.

PostHog also offers a self-hosted option, which matters when a compliance team says recordings cannot sit in a vendor's cloud.

FullStory: replay next to search

FullStory records sessions and indexes what happened inside them, so you can search for behaviour rather than only for events you remembered to instrument.

For example, you can look for sessions containing a rage click, which is when a user clicks the same element several times in a few seconds because nothing responded. That single filter often finds broken buttons before any ticket arrives.

FullStory is the heaviest of the three in terms of setup politics. It is a vendor-hosted product bought by a team, not a library you drop in, and pricing is quoted rather than published.

Privacy: what gets masked, and who decides

Replay is a recording of real people using your product. Treat it as personal data.

Every tool offers three levers:

  1. Input masking. Replace typed characters with asterisks so the value is never sent.
  2. Element blocking. Skip an element entirely, so it appears as a grey box.
  3. Network body capture. Off by default in most tools, because request bodies often hold tokens and personal details.

The defaults differ, and that is the part teams get wrong. rrweb records text and inputs unless you tell it not to. PostHog and FullStory mask input values by default and expect you to open up the fields you actually need.

Bad: unmask a whole checkout form so testers can see what users typed, including the card field.

Good: unmask the country and coupon fields only, and add data-ph-no-capture (PostHog) or the equivalent class on everything else.

Two rules that keep you out of trouble:

  • Mask by default, then open specific fields. Never the other way around.
  • Put anything sensitive behind an element block, not an input mask. Masking protects the value, blocking protects the whole element, including labels and error text.

Retention: how far back can you actually go

Retention is how long a recording stays before it is deleted. It decides whether replay helps with the bug you have today.

Hosted tools sell retention in fixed windows tied to your plan, often a month or a few months, with longer windows on higher tiers. With rrweb you set retention yourself, because it is just files in your own storage.

A bug reported on Monday about "last Tuesday" is fine on any plan. A regression traced back to a release six weeks ago is not. Before you promise a stakeholder that replay will answer a question, check the retention window and check whether the session was sampled at all.

Sampling means recording only a share of sessions, such as 10%, to control cost. If sampling is on, the specific session you want probably does not exist. For QA work, keep sampling at 100% on staging even if production is sampled.

Pricing models and where the bill surprises you

The three tools charge on different units, so a like-for-like comparison of headline numbers is meaningless.

  • rrweb costs nothing to license. You pay for storage, bandwidth, and the engineer who maintains it.
  • PostHog charges per recording captured, with a free monthly allowance. Cost scales with traffic and with how many sessions you choose to record.
  • FullStory charges on quoted plans tied to session volume and seats. You talk to sales.

Two things inflate bills in practice. The first is recording every session on a high-traffic marketing site that nobody ever debugs. The second is turning on network payload capture globally, which multiplies the data per session.

A cheap setup for a QA team: record 100% on staging, sample production, and record 100% only for logged-in users who hit checkout.

What replay cannot show you

This is the part that causes wasted hours, so be blunt about it in your team.

Server state. Replay shows the response arrived and the page rendered an error. It does not show why the API returned 500. It cannot show you the queue depth, the feature flag the server evaluated, or the row that was locked.

Masked input values. If a field is masked, the characters are gone. You will see that the user typed nine characters into the postcode field, not which nine. That is the trade you agreed to when you enabled masking.

Anything outside the page. Browser extensions, native dialogs, print previews, the operating system file picker, and other tabs are invisible. A replay that "freezes" for eight seconds is often a user staring at a native dialog you cannot see.

Canvas, video, and some iframes. Pixels drawn on a <canvas> element are not DOM changes. Many tools skip them or record them at low quality and high cost. Cross-origin iframes are usually blank.

Real timing. Playback timing is reconstructed. Use it to understand order, not to measure performance. For performance numbers, use the browser's own tooling.

How to use replay inside a bug report

A link to a replay is evidence, not a bug report. Reviewers need to know where to look and what else was true at the time.

  1. Copy the replay URL with a timestamp so it opens at the failure, not at second zero.
  2. Write the exact moment in words: "at 02:14 the user clicks Continue and nothing happens".
  3. Add the console error and the failing request, since the replay may not include either.
  4. Note the browser, viewport, and account used, for example Chrome 141 at 1440x900 as [email protected].
  5. Say what the expected behaviour was. A reviewer cannot guess it from the video.

Steps 3 and 4 are the ones people skip, because gathering them by hand means opening DevTools and copying details into the ticket. A browser-based reporting tool such as Crosscheck collects the console output, network requests, and environment details from the page itself when you file the bug, so the replay link arrives with the context it lacks.

Frequently asked questions

Is session replay legal to use on real users?

It depends on your jurisdiction and what you record. Replay usually counts as personal data, so you need a lawful basis, a mention in your privacy notice, and masking on sensitive fields. Ask your legal or privacy owner before enabling it in production.

Does session replay slow down the page?

The recorder adds a script and some ongoing work when the DOM changes a lot. On normal pages the effect is small. On pages with heavy animation or huge tables it is noticeable, so measure before and after on your slowest page.

Can I use replay on staging only?

Yes, and it is a good starting point. Staging has no real user data, so you can record with fewer masking rules and learn the tool before deciding what production should capture.

Why is my replay blank or missing large areas?

The most common causes are blocked elements, cross-origin iframes, and <canvas> content. Check your blocking rules first, since a broad selector such as blocking every div with a private class can hide more than you expected.

Should replay replace written reproduction steps?

No. Steps tell a developer how to reach the bug on their own machine. Replay proves it happened and shows the details a reporter forgot. Ship both.

Related Articles

Contact us
to find out how this model can streamline your business!

Trusted by thousands ofengineering teams worldwide.

Add to Chrome
200+ reviews · 100k+ users
Crosscheck browser extension capture controls

Join the Crosscheck Community

Stay in the loop with Crosscheck's newest features and insights.