Recorded Sessions
Audience: Sales · Support · QA · Engineering · Management · Where in app: Recorded Sessions (/recorded-sessions) · Plan availability: All plans (retention window varies by plan — see Plan & limits)
Every visit is recorded with rrweb. After the visitor leaves, the recording finalizes and is analyzed into structured signals (clicks, scrolls, forms, intent, friction). Admins can browse the list, filter and semantically search it ("people who scrolled past the testimonials and got stuck on pricing"), and replay any session like looking over the visitor's shoulder. This is where teams reconstruct what actually happened before a chat, a booking, or a bounce.
What it does
- Captures and stores every session, then analyzes it into a structured
session_analysesartifact. - Lets admins filter by date range, country, device, traffic source, identified-vs-anonymous, engagement/intent/friction, bot status, and "playable data".
- Supports free-text semantic search across per-visit narrative prose (pgvector
knox_search_index). - Replays the session with full playback controls, an event timeline, page-trip navigator, friction markers, and a conversation overlay.
- Rolls each session up into a per-visitor profile so the AI and Nox see cumulative history.
How it works
Capture
The widget initializes rrweb on page load and captures DOM mutations, mouse moves, scrolls, clicks, inputs, console errors and logs. Events stream to ms-sessions as NDJSON chunks (each chunk carries a first_event_at/last_event_at window), buffered in Redis and drained to S3 in 100-event chunks. Chunk metadata is a counter (session_files.chunk_count, objects named <n>.ndjson) — playback reconstructs names via resolveChunkNames(); legacy files[] arrays are still honored. Session HTTP endpoints are rate-limited (~30/min).
Tenants with consent gating enabled don't capture at all (behaviour category) until the visitor consents; a mid-session grant records forward-only.
Finalization
A session moves active → finalized (a.k.a. stale) when the visitor closes the tab (best-effort), goes idle, or navigates away from every domain the widget is on. Finalize grace is 90s (FINALIZE_GRACE_TTL_SECONDS, was 5min) with a 15s sweep (FINALIZE_SWEEP_INTERVAL_MS, was 30s) — a recording is typically analyzed ~2 minutes after the visitor leaves. The sweep only looks back 2 days (FINALIZE_SWEEP_MAX_AGE_MS). Finalization enqueues a BullMQ recording-analysis job. A backend sweeper (RecordingBackfillSweeperJob, ~every 15 min) re-enqueues any session whose handoff failed.
Analysis pipeline
A separate worker deployment consumes the recording-analysis queue (concurrency ~4, ~120s job timeout; autoscaled on queue depth, ~1–10 pods). It:
- Fetches NDJSON chunks from S3.
- Stitches them into a coherent timeline split by page trip (
stream-stitcher). - Rebuilds the DOM (
dom-resolver) for click/scroll/form context. - Runs extractors — page-trip, click, scroll, form, hover, idle, viewport, error, selection (see Per-Session Signals).
- Synthesizes intent (
intent-synth) — primary intent + confidence + evidence + friction points + high-intent signals. - Geo-backfills the visitor IP → country/city.
- Stitches video frames → MP4 and uploads to S3.
- Rolls up the visitor profile atomically.
- Hands off to ms-ai (
ms-ai-handoffqueue) for embedding/index + selective tier-2 narration.
Result: a session_analyses row keyed by file_id, plus an updated visitor_profiles row.
Naming note: the nox-KB describes extractors under
ms-sessions/app/workers/recording-analysis/processor.js+/extractors/. The deployed worker entrypoint isbin/recording-analysis-worker.js; the analysis stages (dom-resolver,intent-synth,stream-stitcher,geo-backfill) live inapp/workers/recording-analysis/. (verify exact extractor file paths if citing them directly)
Tier-2 narration (selective LLM pass)
For high-value or stuck sessions (visited a high-value page, long dwell, high intent) a second LLM pass writes narrative prose (human summary), a refined intent, and action recommendations. It is capped per company by RECORDING_LLM_DAILY_CAP_PER_COMPANY and policy in companies.knox.high_value_pages[].
Replay
The dashboard plays recordings with rrweb-player (frontend/src/components/SessionPlayer/). Controls: play/pause, playback speed 1x–8x (KB notes 0.5x–4x in one place; UI exposes up to 8x — verify exact range), skip inactive, timeline scrubbing, jump-to-event (clicks/inputs/scroll/navigation), a page-trip navigator, friction markers, and a conversation overlay if a chat/call happened during the session.
Multi-tab playback: Follow Activity mode auto-switches between tabs as the visitor did; Individual Tab view watches one tab in isolation.
Configuration & options
| Setting / field | Where | Effect |
|---|---|---|
companies.knox.high_value_pages[] | Company Nox config | Pages that make a session eligible for tier-2 narration and feed high-intent signals |
RECORDING_LLM_DAILY_CAP_PER_COMPANY | Env | Daily cap on tier-2 LLM narration passes per company |
RECORDING_DOC_SIZE_LIMIT_BYTES | Env | Max recording-doc size before a session is force-finalized/split |
RECORDING_WORKER_CONCURRENCY / RECORDING_WORKER_JOB_TIMEOUT_MS | Worker env | Analysis worker concurrency (~4) and job timeout (~120s) |
| Retention window | Plan | How long replays are kept before pruning (varies by plan — verify exact days per tier) |
| Filters (date/country/device/source/bot/playable) | Recorded Sessions UI | Narrow the list |
For QA/support: "Playable data" filter hides sessions with no meaningful captured activity; "Bot status" hides crawler traffic. Use search-by-name/email to pull all of one visitor's recordings.
Behaviors & edge cases
- Cross-origin iframes are not captured unless the iframe companion script is installed — replay of those regions will be blank.
- Heavy canvas/WebGL pages produce large chunks and may exceed
RECORDING_DOC_SIZE_LIMIT_BYTES, forcing early finalization/splitting. - Tier-2 narration only runs on eligible sessions within the daily cap — most ordinary sessions get structured signals but no prose summary.
- Form input may contain sensitive data. Recordings can capture what visitors typed (except masked/
data-rrweb-blockfields and password inputs). Teams should follow their privacy policy when viewing. - Retention pruning deletes NDJSON chunks from S3 and marks the
session_filesrow archived, butsession_analysesis retained for trend/cohort analysis even after the replay is gone. A blanket retention policy is still undecided; ad-hoc cleanup runs through the Storage Maintenance admin screen (frontend/src/views/admin/StorageMaintenance.vue→POST /admin/storage/session-files-cleanup, dry-run by default). - Global kill switch —
ms-sessionssession_recordings_enabled(hardcoded ON at HEAD) can drop all ingest/playback; a per-session chunk cap was trialled and reverted after a prod incident. - Semantic search matches narrative prose, which only exists for tier-2-narrated sessions — searches may miss sessions that never got a prose pass.
Plan & limits
- Recorded Sessions is on all plans; the retention window (how far back replays are kept) varies by plan — verify exact retention per tier.
- Semantic search quality scales with how many sessions received tier-2 narration, which is capped per company per day.
- B2B company resolution and identity on the visitor info panel depend on enrichment/identity features — see Lead Intelligence.
Technical implementation
- Service:
ms-sessions—RecordedSessionController(list/search/replay),VideoRecordingController+ jobs (RoomVideoMerging,RoomVideoProcessing,DeleteExpiredVideos,DeleteRawVideoFiles) for video synthesis/retention. Worker:bin/recording-analysis-worker.jsconsuming therecording-analysisBullMQ queue, thenms-ai-handoff. - Collections:
session_files(recording metadata +recording_status),session_analyses(per-file structured artifact: page_trips, clicks, scroll metrics, forms, hovers, idles, selections, errors, intent, friction_points, high_intent_signals, optional narrative_prose/action_recommendations),visitor_profiles(one per(company_id, user_session_id): visit_count, recent_sessions cap ~20, cumulative active_ms, unique_pages_visited, recurring_topics/friction, intent_trajectory, engagement_score, conversion_signals, narrative_summary). - Search index:
knox_search_index(pgvector) in ms-ai for semantic search. - Nox tools:
knox-session-analysis(file_id),knox-session-search(query, filters),knox-aggregate(bounce_rate, top_exit_pages, funnel_path…),knox-visitor-profile(user_session_id),knox-history-lookup(person_id). - Subsystems: Session Recording, Identity Graph, Knowledge Base / RAG.
Related
- Live Sessions — watch the same stream in real time
- Per-Session Signals — every field the extractors produce
- Lead Scoring — how session behavior feeds the score
- Booking Sources — attributing a booking back to its session journey
- ms-sessions · Session Recording