Skip to main content

High-Friction Sessions

High-friction sessions is the analytics layer on top of session replay. Capture records what a visitor did on your site; this surface reads those recordings and tells you which ones are worth watching. The dashboard at Insights → High-friction Sessions in the Orbit console scans your recent recorded sessions, derives four frustration signals from each one, and ranks the sessions that show any friction so you triage the worst first — instead of scrubbing recordings one by one. The ranked list and each session’s signal timeline are also available over the API. For the full request/response shapes, see the Session Replay API reference.

What the dashboard ranks

Every recorded session is scored for four frustration signals, each derived from the rrweb events the capture script already stored:
  • Rage clicks — three or more clicks within one second, all inside a 30-pixel radius. The visitor is hammering an element that isn’t responding — a button that looks clickable but isn’t wired, a link that renders as plain text.
  • Dead clicks — a click that produces no DOM change and no navigation within one second. The visitor clicked something that looked interactive but did nothing at all.
  • Error clicks — a click followed within one second by a JavaScript or console error. The click reached a broken code path.
  • U-turns — the visitor navigates to a page and returns to the page they just left within five seconds. They went somewhere, it wasn’t what they wanted, and they bounced straight back.
Each signal contributes to the session’s frustration score: rage clicks and error clicks weigh 3 points each, dead clicks and u-turns weigh 2 points each. A session with one rage click and two u-turns scores 7. A click is only ever counted once — a rage burst is one rage signal, and a click that precedes an error is an error click rather than a dead click — so the score reflects distinct problems, not repeated counting of the same click.

Why these sessions matter

Frustration signals are the pre-contact signal. A visitor who rage-clicks a checkout button or bounces back from your pricing page is heading for either a support conversation or a silent exit — the session-replay capture guide deliberately stops at capture and playback; this surface is where you act on what’s captured, before the visitor reaches the inbox or drops off entirely. Worked into a weekly habit, the ranked list answers “where are visitors struggling this week?” from recordings rather than anecdote, and it names the exact page and moment to fix.

Reading the ranked list

Open Insights → High-friction Sessions. The left column lists your recent recorded sessions, highest frustration score first. Each row shows the page the session started on, when it started, the score, and a per-signal breakdown (for example: 2 rage clicks, 1 u-turn) so you can tell a session full of rage from a session full of bounces at a glance. Ordering is score first, then signal count, then recency — a session with more distinct signals outranks one whose score came from a single burst, and equal-scoring sessions sort newest first. The list scans your 200 most recent recordings and returns up to 100 ranked sessions, so an occasional high-friction spike isn’t buried by a week of smooth traffic. Access follows the session-replay surface itself: any role with the conversations:read scope can view the page and call the API — the same scope that guards replay playback in the inbox.
Each row in the response carries score, signal_count, and a counts breakdown per signal type, plus has_any_recording — which distinguishes “the capture script isn’t installed” (no recordings at all) from “capture is fine, nothing scored” (recordings exist, all friction-free).

The replay player with a marked timeline

Select a session and the player loads the full recording. Directly beneath the player’s scrubber, the signal timeline renders one marker per detected signal, positioned at its fraction of the session — each signal type has its own color, with the legend underneath. Hover a marker for the detail (for example “4 clicks within 900ms” or “returned to /pricing”). Instead of scrubbing a 20-minute recording, you jump straight to the moments the visitor struggled, watch a few seconds of context around each marker, and move on. The timeline is computed over the full recording — including long sessions whose event tail spilled to durable storage — so a rage click near the end of a long session still gets its marker. The same timeline is available per session via GET /api/v1/session-replay/frustration/{conversationId}.

Operator playbook: a weekly drop-off trawl

  1. Open the ranked list once a week and scan the top sessions. Sort mentally by page: a spread of one-off struggles is background noise; a cluster on one page is a defect.
  2. Isolate the cluster. If several top sessions start on — or spend their markers on — the same page (say /checkout), open the top two or three and watch the marked moments. A rage-click marker on the “Pay” button across three visitors in a week is one bug, not three unhappy visitors.
  3. Cross-reference with contact volume. Pull up Contact reasons for the same period. If payment_issue volume surged in the same window, the clip-backed rage clicks explain the surge; if nothing surged, the friction is being absorbed silently — worse for conversion, and cheaper to fix now than after it shows up in the contact volume.
  4. Hand off to product. For each session that confirms the pattern, note the page, the signal type, and the timestamp of the marker. A two-clip summary — “three rage clicks on the Pay button, here and here” — gets the fix prioritized far faster than “customers seem frustrated with checkout.”
  5. Verify the fix. After the change ships, the same trawl next week should show the cluster gone from the ranked list. If the page disappears from the list entirely, the fix worked; if it stays, reopen with the new markers.

Boundary cases

  • Sessions with no signals. Friction-free sessions never appear in the ranked list — absence is a good result, not missing data. The overall score is 0 whenever none of the four detection windows trips.
  • Sessions too short to score. A recording needs at least a full snapshot plus one incremental event to play back, and extremely short visits (a bounce before the first interaction settles) may hold too few events for any window to trip. Such sessions simply never rank; the player tells you “too short to play back” when it applies.
  • No recordings at all. If the list is empty and has_any_recording is false, capture isn’t running — verify the widget is installed and recording, using the steps in Verifying capture, before assuming visitors were friction-free.
  • Purged or deleted recordings. Frustration signals are derived on read from the stored recording — purge the recording (or delete its conversation) and the session drops out of the list on the next scan. Erasure behavior follows the same rules as replay itself.

See also

  • Session replay — capture, retention, playback in the inbox, and privacy masking
  • Contact reasons — the macro view of why customers reach you, for surge confirmation
  • Session Replay API reference — endpoint shapes for the ranked list and per-session timeline
  • Co-browse — the live counterpart when an agent should watch in real time instead