---
title: "Replay"
description: "Session recording protocol for capturing and streaming browser or mobile user sessions to Sentry."
url: https://develop.sentry.dev/sdk/telemetry/replays/
---

# Replay

This document uses key words such as "MUST", "SHOULD", and "MAY" as defined in

<!-- -->

[RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) to indicate requirement levels.

Statusstable

Version`1.2.0`[(changelog)](https://develop.sentry.dev/sdk/telemetry/replays.md#changelog)

## [Overview](https://develop.sentry.dev/sdk/telemetry/replays.md#overview)

Replay captures a recording of a user's browser or mobile session and streams it to Sentry in segments. Each segment consists of two envelope items sent together: a `replay_event` (metadata about the replay) and a `replay_recording` (the actual recording data). Sentry stitches segments into a continuous replay for debugging.

Related specs:

* [Envelopes](https://develop.sentry.dev/sdk/foundations/transport/envelopes.md) — transport format
* [Envelope Items](https://develop.sentry.dev/sdk/foundations/transport/envelope-items.md) — `replay_event` and `replay_recording` item type constraints
* [Replay Recording Events](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/replay-recording.md) — recording instruction set format

***

## [Concepts](https://develop.sentry.dev/sdk/telemetry/replays.md#concepts)

### [Replay Modes](https://develop.sentry.dev/sdk/telemetry/replays.md#replay-modes)

Replay operates in one of two modes:

* **Session mode** (`sessionSampleRate`) — Recording starts immediately at SDK initialization and streams continuously to Sentry.
* **Buffer mode** (`onErrorSampleRate`) — Recording starts at SDK initialization but is buffered in-memory (ring buffer). Capture is only triggered by an error or manual flush.

### [Segments](https://develop.sentry.dev/sdk/telemetry/replays.md#segments)

A replay is composed of **segments**, each identified by a `segment_id` (starting at 0). Each segment is sent as a pair of envelope items: a `replay_event` containing metadata and a `replay_recording` containing the actual recording data.

***

## [Behavior](https://develop.sentry.dev/sdk/telemetry/replays.md#behavior)

### [Session Mode](https://develop.sentry.dev/sdk/telemetry/replays.md#session-mode)

Stablespecified since

<!-- -->

1.1.0

When an SDK records Session Replay in `session` mode (`sessionSampleRate` is specified), the recording **SHOULD** start when the SDK is initialized and **MUST** be continuously streamed to the Sentry servers. SDKs **SHOULD** send a replay envelope every 5 seconds.

The maximum duration of the recording **MUST NOT** exceed 60 minutes (or 15 minutes without activity on Web). (since 1.2.0) After the hard limit has been reached, the SDK **MUST** stop recording, clear the current `replay_id`, and remove it from the Scope so all subsequent events are not associated with it.

For SDKs that support disk cache, the recording **SHOULD** pause when there is no internet connection or the SDK is being rate-limited. This prevents overflowing the disk cache, which can result in losing more critical envelopes. When internet connection is restored or the rate limit is lifted, the recording **SHOULD** resume.

### [Buffer Mode](https://develop.sentry.dev/sdk/telemetry/replays.md#buffer-mode)

Stablespecified since

<!-- -->

1.1.0

When an SDK records Session Replay in `buffer` mode (`onErrorSampleRate` is specified), the recording **SHOULD** start when the SDK is initialized and **MUST** be buffered in-memory (and to disk if the SDK supports disk cache) in a ring buffer for up to 30 seconds back.

Capturing of the recording **MAY** be triggered when one of the following conditions is met:

* A crash or error event occurs and is captured by the SDK.
* The `flush` API has been called manually on the replay (for SDKs that support manual API).

After the initial (buffered) segment has been captured, the SDK **SHOULD** continue recording in `session` mode. The `replay_type` field of subsequent segments **MUST** still be set to `buffer` to reflect the original replay type.

If the crash or error event has been dropped in `beforeSend`, the replay **MUST NOT** be captured.

***

## [Wire Format](https://develop.sentry.dev/sdk/telemetry/replays.md#wire-format)

### [Replay Event Payload](https://develop.sentry.dev/sdk/telemetry/replays.md#replay-event-payload)

Stablespecified since

<!-- -->

1.0.0

A `replay_event` envelope item **MUST** always be sent together with a `replay_recording` item in the same envelope. An envelope **MUST** contain at most one `replay_event` item.

#### [Replay Attributes](https://develop.sentry.dev/sdk/telemetry/replays.md#replay-attributes)

| Field                    | Type          | Required                     | Since | Description                                                                                                                                                                                                                              |
| ------------------------ | ------------- | ---------------------------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`                   | String        | **REQUIRED**                 | 1.0.0 | **MUST** be `"replay_event"`.                                                                                                                                                                                                            |
| `replay_id`              | String        | **REQUIRED**                 | 1.0.0 | A unique ID for the replay. Follows the [same requirements](https://develop.sentry.dev/sdk/foundations/transport/event-payloads.md#required-attributes) as `event_id`: hexadecimal UUID v4, exactly 32 characters, lowercase, no dashes. |
| `replay_type`            | String        | **REQUIRED**                 | 1.0.0 | One of `"session"` or `"buffer"`. Describes the mode of the replay.                                                                                                                                                                      |
| `segment_id`             | Number        | **REQUIRED**                 | 1.0.0 | The segment identifier, starting at 0.                                                                                                                                                                                                   |
| `replay_start_timestamp` | Number        | **REQUIRED** (first segment) | 1.0.0 | UNIX timestamp of the start of the replay (in seconds). Only required on the first segment.                                                                                                                                              |
| `urls`                   | List\[String] | **OPTIONAL**                 | 1.0.0 | List of URLs in order of visitation.                                                                                                                                                                                                     |
| `trace_ids`              | List\[String] | **OPTIONAL**                 | 1.0.0 | List of trace IDs that occurred during the replay.                                                                                                                                                                                       |
| `error_ids`              | List\[String] | **DEPRECATED**               | 1.0.0 | Deprecated. Do not use.                                                                                                                                                                                                                  |

#### [Event Attributes](https://develop.sentry.dev/sdk/telemetry/replays.md#event-attributes)

The following attributes are a subset of the [optional attributes](https://develop.sentry.dev/sdk/foundations/transport/event-payloads.md#optional-attributes) of an Event.

| Field                        | Type   | Required     | Since | Description                                      |
| ---------------------------- | ------ | ------------ | ----- | ------------------------------------------------ |
| `timestamp`                  | Number | **REQUIRED** | 1.0.0 | UNIX timestamp of the current time (in seconds). |
| `event_id`                   | String | **REQUIRED** | 1.0.0 | **MUST** be the same as `replay_id`.             |
| `platform`                   | String | **OPTIONAL** | 1.0.0 | Platform of the SDK.                             |
| `environment`                | String | **OPTIONAL** | 1.0.0 | The environment name.                            |
| `release`                    | String | **OPTIONAL** | 1.0.0 | The release version.                             |
| `dist`                       | String | **OPTIONAL** | 1.0.0 | The distribution identifier.                     |
| `user.id`                    | String | **OPTIONAL** | 1.0.0 | User identifier.                                 |
| `user.username`              | String | **OPTIONAL** | 1.0.0 | Username.                                        |
| `user.email`                 | String | **OPTIONAL** | 1.0.0 | User email.                                      |
| `user.ip_address`            | String | **OPTIONAL** | 1.0.0 | User IP address.                                 |
| `sdk.name`                   | String | **OPTIONAL** | 1.0.0 | SDK name.                                        |
| `sdk.version`                | String | **OPTIONAL** | 1.0.0 | SDK version.                                     |
| `request.url`                | String | **OPTIONAL** | 1.0.0 | Current request URL.                             |
| `request.headers.User-Agent` | String | **OPTIONAL** | 1.0.0 | User agent string.                               |

### [Replay Recording Item](https://develop.sentry.dev/sdk/telemetry/replays.md#replay-recording-item)

Stablespecified since

<!-- -->

1.0.0

An envelope **MUST** contain at most one `replay_recording` item. The `length` item header is **REQUIRED** and specifies the size of the recording payload.

The `replay_recording` item consists of two sub-items delimited by a newline:

1. **Metadata** — a JSON object. Currently only `segment_id` is required:

```json
{ "segment_id": 0 }
```

2. **Recording payload** — the replay recording instruction set. This payload **SHOULD** be gzipped, but uncompressed payloads are also accepted. See [Replay Recording Events](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/replay-recording.md) for the recording format.

***

## [Public API](https://develop.sentry.dev/sdk/telemetry/replays.md#public-api)

### [Session Sample Rate](https://develop.sentry.dev/sdk/telemetry/replays.md#session-sample-rate)

Stablespecified since

<!-- -->

1.0.0

SDKs **MUST** accept a `replaysSessionSampleRate` configuration option (number, 0.0–1.0, default 0). This controls the fraction of sessions recorded in session mode. `1.0` records all sessions, `0` records none.

Naming **SHOULD** follow the SDK's language conventions:

* `replaysSessionSampleRate` (JavaScript)
* `replays_session_sample_rate` (Python)

### [Error Sample Rate](https://develop.sentry.dev/sdk/telemetry/replays.md#error-sample-rate)

Stablespecified since

<!-- -->

1.0.0

SDKs **MUST** accept a `replaysOnErrorSampleRate` configuration option (number, 0.0–1.0, default 0). This controls the fraction of sessions buffered for error replay. `1.0` captures all sessions with an error, `0` captures none.

Naming **SHOULD** follow the SDK's language conventions:

* `replaysOnErrorSampleRate` (JavaScript)
* `replays_on_error_sample_rate` (Python)

### [Replay Integration](https://develop.sentry.dev/sdk/telemetry/replays.md#replay-integration)

Stablespecified since

<!-- -->

1.0.0

SDKs **MUST** provide a replay integration that initializes the recording subsystem:

```bash
replayIntegration(options?) -> Integration
```

SDKs **MAY** accept privacy and configuration options (text masking, media blocking, network capture settings).

Naming **SHOULD** follow the SDK's language conventions:

* `replayIntegration()` (JavaScript)
* `SessionReplayIntegration()` (Python)
* `SentryReplay` / `SessionReplay` (mobile SDKs)

### [Get Replay Instance](https://develop.sentry.dev/sdk/telemetry/replays.md#get-replay-instance)

Stablespecified since

<!-- -->

1.0.0

SDKs **SHOULD** expose a function to retrieve the active replay instance:

```bash
getReplay() -> replayInstance | null
```

Returns the replay integration instance if replay is initialized, or `null` if not. The returned instance provides the runtime control methods documented below.

### [Get Replay ID](https://develop.sentry.dev/sdk/telemetry/replays.md#get-replay-id)

Stablespecified since

<!-- -->

1.0.0

The replay instance **MUST** expose a method to retrieve the current replay identifier:

```bash
replayInstance.getReplayId() -> replayId | null
```

Returns the current `replay_id` (string) if a replay is active, or `null` if no replay is recording or buffering. This is useful for checking whether a replay is active before calling other runtime methods.

### [Start](https://develop.sentry.dev/sdk/telemetry/replays.md#start)

Stablespecified since

<!-- -->

1.1.0

The replay instance **SHOULD** expose a method to manually start recording in session mode:

```bash
replayInstance.start() -> void
```

Starts recording in session mode regardless of sample rates. If a session is already running, this **SHOULD** be a no-op.

### [Start Buffering](https://develop.sentry.dev/sdk/telemetry/replays.md#start-buffering)

Stablespecified since

<!-- -->

1.1.0

The replay instance **SHOULD** expose a method to manually start recording in buffer mode:

```bash
replayInstance.startBuffering() -> void
```

Starts recording in buffer mode regardless of sample rates. If a session is already running, this **SHOULD** be a no-op.

### [Stop](https://develop.sentry.dev/sdk/telemetry/replays.md#stop)

Stablespecified since

<!-- -->

1.1.0

The replay instance **SHOULD** expose a method to stop recording:

```bash
replayInstance.stop() -> Promise<void>
```

Flushes any pending recording data, stops the replay, and ends the session.

### [Flush](https://develop.sentry.dev/sdk/telemetry/replays.md#flush)

Stablespecified since

<!-- -->

1.1.0

The replay instance **SHOULD** expose a method to flush pending recording data:

```bash
replayInstance.flush() -> Promise<void>
```

In session mode, this uploads pending recording data to Sentry. In buffer mode, this uploads the buffered data and continues recording (same as when an error triggers capture). Calling `flush()` while replay is stopped **MAY** start a new session recording.

***

## [Examples](https://develop.sentry.dev/sdk/telemetry/replays.md#examples)

### [SDK API Usage](https://develop.sentry.dev/sdk/telemetry/replays.md#sdk-api-usage)

```javascript
import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  integrations: [Sentry.replayIntegration()],
});

// Manual control
const replay = Sentry.getReplay();
replay.start(); // start session-mode recording
replay.flush(); // flush buffered data
await replay.stop(); // stop and end session
```

### [Replay Event](https://develop.sentry.dev/sdk/telemetry/replays.md#replay-event)

```json
{
  "type": "replay_event",
  "replay_id": "36b75d9fa11f45459412a96c41bdf691",
  "replay_start_timestamp": 1710861499.287,
  "replay_type": "session",
  "segment_id": 0,
  "trace_ids": ["905aef2282af5fe2ab2c93aa7a340521"],
  "urls": [
    "https://sentry.io/issues/",
    "https://sentry.io/issues/?project=0&statsPeriod=7d&utc=true"
  ],

  "request": {
    "url": "https://sentry.io/issues/?project=0&statsPeriod=7d&utc=true",
    "headers": {
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
    }
  },
  "timestamp": 1710861507.579,
  "event_id": "36b75d9fa11f45459412a96c41bdf691",
  "environment": "prod",
  "release": "frontend@f00",
  "sdk": {
    "integrations": [
      "BrowserTracing",
      "BrowserProfiling",
      "Replay",
      "ReplayCanvas"
    ],
    "name": "sentry.javascript.react",
    "version": "7.105.0"
  },
  "tags": {
    "sentry_version": "24.4.0.dev0"
  },
  "user": {
    "ip_address": "127.0.0.1",
    "email": "admin@sentry.io",
    "id": 1,
    "name": "Admin"
  },
  "contexts": { "organization": { "id": "0", "slug": "sentry" } },
  "platform": "javascript"
}
```

### [Replay Recording](https://develop.sentry.dev/sdk/telemetry/replays.md#replay-recording)

```bash
{"segment_id": 0}
\x00\x00\x00\x14ftypqt  \x00\x00\x00\x00qt  \x00\x00\x00\x08wide\x03\xbdd\x11mdat
```

### [Full Envelope](https://develop.sentry.dev/sdk/telemetry/replays.md#full-envelope)

```json
{"event_id":"36b75d9fa11f45459412a96c41bdf691","sent_at":"2024-03-19T15:18:27.581Z","sdk":{"name":"sentry.javascript.react","version":"7.105.0"}}
{"type":"replay_event"}
{
  "type": "replay_event",
  "replay_id": "36b75d9fa11f45459412a96c41bdf691",
  "replay_start_timestamp": 1710861499.287,
  "replay_type": "session",
  "segment_id": 0,
  "trace_ids": ["905aef2282af5fe2ab2c93aa7a340521"],
  "urls": [
    "https://sentry.io/issues/",
    "https://sentry.io/issues/?project=0&statsPeriod=7d&utc=true"
  ],

  "request": {
    "url": "https://sentry.io/issues/?project=0&statsPeriod=7d&utc=true",
    "headers": {
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
    }
  },
  "timestamp": 1710861507.579,
  "event_id": "36b75d9fa11f45459412a96c41bdf691",
  "environment": "prod",
  "release": "frontend@f00",
  "sdk": {
    "integrations": [
      "BrowserTracing",
      "BrowserProfiling",
      "Replay",
      "ReplayCanvas"
    ],
    "name": "sentry.javascript.react",
    "version": "7.105.0"
  },
  "tags": {
    "sentry_version": "24.4.0.dev0"
  },
  "user": {
    "ip_address": "127.0.0.1",
    "email": "admin@sentry.io",
    "id": 1,
    "name": "Admin"
  },
  "contexts": { "organization": { "id": "0", "slug": "sentry" } },
  "platform": "javascript"
}
{"type":"replay_recording","length":141666}
{"segment_id":0}
/* gzipped JSON payload */
```

***

## [Changelog](https://develop.sentry.dev/sdk/telemetry/replays.md#changelog)

| Version | Date       | Summary                                                                                      |
| ------- | ---------- | -------------------------------------------------------------------------------------------- |
| `1.2.0` | 2025-07-30 | Added session mode hard limit behavior (stop recording, clear replay\_id, remove from scope) |
| `1.1.0` | 2025-07-29 | Added SDK behavior for session mode and buffer mode                                          |
| `1.0.0` | 2024-08-15 | Initial spec — replay\_event and replay\_recording wire format                               |
