Session recordings

PennyLens captures session recordings by serializing DOM mutations through rrweb — not by recording the screen. Recordings are pixel-perfect, render at native resolution on any device, and weigh a fraction of what a video-based replay tool produces.

This page covers what's captured by default, how to control it per-element and per-page, and how retention works across plans.

What's captured

By default, every session records:

  • Full DOM at session start, then mutation deltas as the user interacts.
  • Click, scroll, mouse movement, and viewport resize events.
  • Form interactions — focus, blur, completion timing, and submission.

What's not captured

We never capture:

  • Form values matched by our redaction rules — passwords, card numbers, social security numbers.
  • Contents of <input type="password"> regardless of name.
  • Audio, video, or media streams.
  • Raw IP addresses (anonymized at ingestion).

Default masking

All <input>, <textarea>, and <select> values are masked in the recording stream by default. The user's interactions — where they typed, when they tabbed away, how long the field took to complete — are preserved. The values themselves are not.

This is a hard default: input masking cannot be turned off, on any plan or environment, including internal staging.

Per-element controls

Decorate elements with data-pl-* attributes to override the default behavior:

| Attribute | Effect | | --- | --- | | data-pl-mask | Mask the element's text content (replaces visible text with placeholder characters in the recording). Useful for displayed PII like full names or addresses. | | data-pl-ignore | Exclude the element from recordings entirely — neither the DOM node nor any mutations on it are captured. |

Both attributes propagate to descendants — applying one to a container covers everything inside it.

<!-- Mask user-displayed PII -->
<div data-pl-mask>Welcome back, Alex Rivera</div>

<!-- Hide an entire payment widget -->
<form data-pl-ignore>
  <input type="text" name="card-number" />
</form>

Disabling recording entirely

To skip recordings across the whole site, pass sessionRecording: false to init — the recording layer never attaches and the SDK runs in events-only mode.

PennyLens.init({
  projectId: "YOUR_API_KEY", // your API key from Settings, not the project id
  sessionRecording: false,
});

The other capture layers (events, heatmaps, scroll depth, form analytics) continue to work.

Retention

Retention windows by plan:

| Plan | Recording retention | | --- | --- | | Free | 30 days | | Pro | 30 days | | Business | 90 days |

After expiry, the recording itself is deleted. Aggregate metrics derived from it — heatmaps, click density, scroll depth — are kept under the longer events-retention window.

Seekable timeline

The replay scrubber shows a color-coded marker for every click, page view, scroll, and form interaction in the session — hover a marker for its label and timestamp, or click it to jump straight there instead of scrubbing blind.

Rage clicks and dead clicks are detected separately as project-wide AI insights (see Product) — they don't yet appear as individual scrubber markers inside a single recording.

Privacy and compliance

  • All recordings are stored encrypted at rest (AES-256) in your project's chosen region.
  • Recordings are streamed only to authenticated dashboard users with access to the project.
  • For GDPR right-to-deletion requests, contact privacy@pennylens.com — recordings and associated events are purged within 30 days. See the Privacy Policy for the full deletion pipeline.
  • Subprocessors with access to recording storage are listed in the Privacy Policy.

Next steps