What self-hosted session replay actually means
“Self-hosted session replay” is often used for several different architectures. A team may host only a collection endpoint, operate the complete replay data plane, run an internal replay application, or divide those responsibilities between internal and managed services.
The distinction matters. A security review, cost model, and staffing estimate will be misleading unless the team first identifies which layers it owns.
Self-hosted recorder endpoint
In the narrowest model, the browser recorder sends events to an endpoint operated by the company.
The company controls the endpoint’s domain, authentication, request validation, and immediate routing. The data might then enter internal storage and processing, or it might be forwarded to another service.
This model can improve control over first-party collection and network paths, but it does not necessarily mean the company controls long-term storage, processing, replay search, or the user interface.
Self-hosted storage and processing
In a broader model, the company operates the replay data plane:
- ingestion;
- durable queues or streams;
- recording storage;
- background processing;
- session manifests;
- metadata databases;
- searchable indexes;
- retention and deletion jobs.
This is where most capacity, reliability, backup, and operational work appears. A browser SDK may be relatively small, while the data plane must handle continuous writes, retries, duplication, partial sessions, retention, access, and growth.
Self-hosted application
A complete self-hosted replay application also includes the tools people use to find and inspect recordings:
- project and environment administration;
- user and company identity mapping;
- session search;
- authorization;
- replay loading;
- the player;
- audit history;
- privacy configuration;
- retention controls;
- deletion administration;
- operational diagnostics.
Operating the application means owning both the recording pipeline and the experience through which employees access privacy-sensitive behavioral evidence.
Hybrid model
A hybrid model divides responsibility. Examples include:
- internal ingestion with managed processing;
- internal storage with a managed search or playback layer;
- managed replay with region-specific storage or private networking;
- internal product analytics with managed replay only for selected sessions;
- short-lived managed recordings combined with long-lived internal aggregate analytics.
Not every vendor or open-source project supports every combination. Treat these as architectural patterns to investigate, not assumptions about a particular provider.
A useful self-hosting statement is therefore specific:
Example responsibility statement“We operate the browser configuration, collection endpoint, queue, recording storage, metadata database, replay application, access control, and deletion service in these regions.”
That is much clearer than saying only, “We host rrweb.”
A reference architecture for self-hosted session replay
A practical replay architecture has three connected paths:
- Capture and ingestion: browser events become durable recording chunks.
- Search and playback: an authorized viewer finds a visit and loads its manifest and chunks.
- Governance and operations: identity, access, retention, deletion, backups, monitoring, and administration apply across the system.
The architecture below is a reference model, not a universal technology prescription.
1. Browser recorder
The recorder observes configured page and interaction changes, applies masking or blocking rules, samples high-frequency signals, and emits replay events.
For rrweb-based recording, the recorder and replayer are separate concerns. rrweb documents recording, replay, masking, blocking, sampling, canvas options, compression hooks, and plugins. It does not provide the complete surrounding production platform.
The recorder should attach a stable envelope to each batch, such as:
- project identifier;
- session or visit identifier;
- anonymous batch identifier;
- batch sequence number;
- recorder version;
- event-format version;
- plugin versions;
- compression codec;
- client timestamps;
- capture-policy version.
Avoid putting sensitive user information directly into storage keys or transport identifiers when an opaque identifier can be used instead.
2. Ingestion API
The browser sends batches to a collection API. That API should terminate TLS, enforce request limits, validate payload structure, reject unsupported formats, and return an explicit acceptance result.
The ingestion API should do as little synchronous work as practical. Heavy assembly, indexing, compression, or enrichment can increase latency and make spikes harder to absorb.
3. Authentication and project validation
A write credential should identify the permitted project or environment and nothing broader.
Ingestion authentication and replay-viewer authentication are different problems:
- the browser needs narrowly scoped permission to submit recording data;
- an employee or service account needs permission to search for and view specific recordings;
- an administrator may need permission to change retention, masking, or access settings.
Do not treat possession of a project write key as permission to read recordings.
4. Rate limiting and abuse prevention
Replay endpoints consume bandwidth, CPU, queue capacity, storage, and money. They therefore need controls for:
- requests per credential;
- bytes per credential;
- oversized batches;
- malformed payloads;
- repeated authorization failures;
- excessive session creation;
- abusive retry loops;
- unexpected origins;
- sudden project-level volume changes.
Rate limiting should account for legitimate product bursts. A global request count alone can punish high-traffic customers while failing to stop a small number of extremely large payloads.
5. Event batching
Sending every replay event as a separate request creates unnecessary overhead. Most implementations batch by time, byte size, event count, or a combination.
The batching policy affects:
- request volume;
- memory usage in the browser;
- data lost when a page closes;
- latency before events become durable;
- object count;
- queue message count;
- replay startup behavior.
Smaller batches reduce the amount at risk before a flush but increase request and object overhead. Larger batches are more efficient but can lose a longer interval when the browser disappears before transmission.
6. Durable queue or stream
A queue or stream separates browser-facing ingestion from background processing.
Its purpose is not merely speed. It provides a durable boundary that can absorb temporary downstream failure and smooth traffic spikes.
The consumer must still handle the delivery semantics of the selected system. For example, standard Amazon SQS queues document at-least-once delivery and possible out-of-order messages. Apache Kafka documents ordering within a partition rather than across an entire topic. A replay pipeline should therefore be idempotent and should define how events for one visit are partitioned, sequenced, retried, and deduplicated.
7. Raw recording object storage
Compressed recording chunks often fit object-storage access patterns:
- append new immutable objects;
- read a known set of objects for playback;
- expire objects after a retention period;
- transition older data to another tier;
- replicate or back up according to policy.
An example object key might use opaque identifiers:
recordings/{project_id}/{date_partition}/{visit_id}/{sequence}.bin
The key design should support project isolation and lifecycle rules without exposing user names, email addresses, company names, or page content.
8. Metadata database and searchable index
Recording bytes are not enough. Teams need to find a relevant visit by project, date, user, company, product area, grouped page, release, browser, device, error state, or another operational signal.
A relational or analytical database can hold:
- visit metadata;
- identity references;
- chunk records;
- start and end timestamps;
- recorder and format versions;
- capture-policy version;
- processing status;
- retention status;
- deletion status;
- replay health.
A separate search index may be justified when query patterns, scale, or text-search requirements exceed the metadata database’s intended workload. It should not be added automatically: every index adds storage, update, deletion, security, and backup work.
9. Session assembly and processing
Background workers may:
- validate sequence ranges;
- deduplicate batches;
- decompress and inspect envelopes;
- create or update manifests;
- derive page and timing metadata;
- connect a visit to a user and company;
- identify missing chunks;
- mark a recording playable or partial;
- write searchable fields;
- schedule retention.
Processing should be restartable. Replaying the same queue message should not create duplicate chunks or duplicate metadata.
10. Replay player
The player loads a manifest, fetches the required chunks, decompresses them, and reconstructs the recorded page state and event sequence.
A usable player also needs:
- progressive loading;
- error handling;
- seeking;
- speed controls;
- long-visit behavior;
- missing-chunk behavior;
- version-aware replay;
- plugin support;
- memory limits;
- useful diagnostics when playback fails.
Storing replay bytes is easier than delivering responsive playback across many recording shapes and ages.
11. User and company identity mapping
For B2B SaaS, a session becomes more useful when it is connected to both the individual User and the customer Company.
Identity mapping should be explicit and reviewable. It should account for:
- users changing company membership;
- shared or service accounts;
- identity aliases;
- delayed identification;
- users present in more than one workspace;
- deleted users;
- merged companies;
- environment separation.
A replay should not be associated with another Company merely because a client-supplied identifier was accepted without project-scoped validation.
12. Access-control layer
Replay access is usually more sensitive than access to an aggregate chart. The authorization layer should decide whether the current viewer can access:
- the project;
- the environment;
- the Company;
- the User;
- the specific visit;
- raw recording chunks;
- restricted routes or product areas;
- administrative privacy settings.
Apply authorization before issuing signed object URLs or streaming recording bytes. Short-lived signed access reduces the need to expose broad storage credentials, but the application must still verify authorization each time it grants access.
13. Retention and deletion service
A dedicated service or workflow should coordinate deletion across:
- recording objects;
- manifests;
- metadata rows;
- search indexes;
- caches;
- derived artifacts;
- access links;
- backups according to backup policy.
Object lifecycle rules are useful, but they do not automatically remove indexed references, cached manifests, database records, or noncurrent object versions.
14. Backup and disaster recovery
The team should define what is backed up, why, and how it is restored.
Possible choices include:
- backing up only metadata because recording objects are replicated;
- maintaining a separate copy of both objects and metadata;
- continuous database recovery with a shorter object-retention window;
- treating replay as reconstructable or noncritical and accepting limited recovery;
- retaining deletion ledgers independently from recordings.
A backup that has never been restored in a test is an assumption, not a recovery plan.
15. Monitoring and alerting
Observe the complete path from browser submission to successful replay, not only server uptime.
A healthy ingestion API can still produce unusable recordings when chunks are reordered, processing is delayed, authorization fails, manifests are corrupt, or player versions are incompatible.
16. Administrative tools
Operators need a safe way to:
- inspect failed batches;
- replay processing jobs;
- identify unsupported versions;
- verify deletion;
- review storage growth;
- disable a compromised project key;
- pause one project;
- update capture policies;
- trace a visit through the pipeline;
- inspect access history;
- test backup restoration.
Avoid making direct database or bucket access the normal administration interface.
Why not store every replay payload as an ordinary relational row?
A relational database can store large values. PostgreSQL, for example, documents TOAST, which can compress and move oversized field values out of the main table page. That capability does not mean large replay payloads are automatically the best relational workload.
Before storing complete recordings as ordinary rows, consider:
- append volume;
- row and table bloat;
- write-ahead-log volume;
- replication traffic;
- backup size and restore time;
- deletion behavior;
- large-row reads;
- query isolation;
- retention partitions;
- object count versus row count;
- how frequently recordings are read;
- whether clients need partial chunk access.
Object storage plus relational metadata is a common separation because the access patterns differ. It is not a law. A small installation may reasonably begin with a simpler model, while a specialized analytical system may choose another architecture. Make the decision from measured volume, access patterns, recovery requirements, and operational competence.
Recorder and player compatibility is a long-term responsibility
A recording is useful only if a player can interpret it later.
That creates a compatibility contract between:
- the browser recorder;
- the event schema;
- rrweb or another replay library;
- custom record plugins;
- custom replay plugins;
- compression;
- stored assets;
- processing code;
- the replay player.
Version the recording envelope
Store enough version information to choose the correct decoding and playback path. At minimum, consider:
recording_schema_version
recorder_bundle_version
replay_library_version
rrweb_event_version
record_plugin_versions
compression_codec
compression_version
capture_policy_version
created_at
Do not rely only on the application deployment date. A cached browser bundle can continue sending an older format after a new release.
Upgrade the recorder and player deliberately
A recorder upgrade can change:
- emitted event shapes;
- default behavior;
- event frequency;
- masking behavior;
- canvas capture;
- stylesheet handling;
- plugin payloads;
- compression;
- browser compatibility.
A player upgrade can change how old snapshots, mutations, fonts, styles, canvases, media, or plugins are reconstructed.
Deploying both together does not solve legacy playback. Recordings already in storage were created by older code.
Treat plugins as part of the format
rrweb’s plugin documentation separates record and replay plugins and recommends versioned plugin names. That is an important operational clue: a custom record plugin needs a compatible replay handler.
A plugin that records console, network, canvas, or custom product events can create an implicit schema dependency. Preserve its version in the recording envelope and keep a test fixture for it.
Keep compression symmetrical
rrweb documents packFn for recording and unpackFn for replay, as well as backend compression of a complete session.
If compression changes, store the codec and version with each object or manifest. A player should not have to guess whether a payload is plain JSON, packed events, gzip, Brotli, or a custom binary format.
Decide how old recordings will remain playable
Common strategies include:
- keep a player capable of reading all unexpired formats;
- bundle a legacy player for older format ranges;
- migrate recordings to a new format;
- limit compatibility to the maximum retention period;
- mark unsupported recordings clearly rather than failing silently.
Migration can be expensive because it reads, transforms, and rewrites a large archive. Retaining multiple player runtimes increases dependency and security maintenance. A short retention period reduces the compatibility horizon but does not eliminate the need for upgrade testing.
Maintain compatibility fixtures
Keep a small, controlled library of retained test recordings that covers:
- each supported recorder version;
- each supported event schema;
- each compression method;
- each custom plugin;
- masked and blocked elements;
- page navigation;
- long DOM mutation sequences;
- canvas capture when enabled;
- network or console capture when enabled;
- a partial recording;
- a recording with missing assets;
- a very long visit.
Run those fixtures against new player builds before deployment. The test should confirm not only that playback starts, but that representative checkpoints render and seek correctly.
Ingestion reliability: complete-looking replays can still be incomplete
Replay ingestion is an unreliable distributed workflow beginning in a browser you do not control.
The user can close the page. The device can sleep. A mobile browser can suspend the tab. A network can disappear. A proxy can reject a payload. A retry can duplicate a batch. A queue can redeliver a message. A clock can be wrong.
The difficult failure mode is not always a blank player. It is a replay that looks plausible while omitting the interaction that mattered.
Batch for efficiency, but preserve identity and order
Each batch should carry:
- visit ID;
- batch ID;
- monotonically increasing sequence number;
- first and last event timestamp;
- event count;
- byte count;
- format version;
- checksum where useful.
Use the batch ID as an idempotency key. Receiving the same batch twice should not create two copies of its events.
Sequence numbers let the processor detect gaps. Do not infer order only from server arrival time.
Design retries around ambiguity
A client can time out after the server has already accepted a batch. Retrying is therefore necessary, and duplicate delivery is normal.
The server should distinguish:
- not received;
- received but not yet durable;
- durably accepted;
- rejected as invalid;
- rejected as unauthorized;
- rejected because of policy or capacity.
Return a stable result for an already accepted batch rather than treating the retry as a new write.
Page-close delivery is useful but limited
navigator.sendBeacon() is intended for small asynchronous analytics payloads and avoids delaying navigation. fetch() with keepalive provides more request flexibility. Neither mechanism recovers events after a browser crash, power loss, or prolonged offline period.
A robust recorder may combine:
- periodic flushing;
- byte-based flushing;
- a visibility-change flush;
- bounded local buffering;
- retry with backoff;
- an upper limit on local storage;
- clear behavior when capture exceeds that limit.
Do not keep privacy-sensitive replay data indefinitely in browser storage merely to improve delivery.
Handle partial sessions explicitly
A visit can be partial because:
- recording began after page load;
- the first batch was lost;
- a middle batch is missing;
- the final flush did not complete;
- processing failed;
- the retention boundary removed early chunks;
- one region could not reach another;
- a payload exceeded a limit.
Expose recording health such as:
- complete;
- partial at start;
- missing sequence range;
- partial at end;
- unsupported format;
- processing failed;
- deleted;
- expired.
The player should explain missing data rather than presenting an apparently complete timeline without qualification.
Plan for backpressure and spikes
A product launch, customer import, script loop, or masking regression can change ingest volume quickly.
Backpressure controls can include:
- bounded queue depth;
- per-project byte quotas;
- client sampling changes;
- batch-size limits;
- circuit breakers;
- delayed nonessential processing;
- dead-letter handling;
- project-level suspension;
- autoscaling where supported.
Dropping data without marking affected visits is dangerous. When degradation is necessary, record which projects, periods, or visits were affected.
Treat multi-region ingestion as a consistency decision
A nearby endpoint can reduce browser latency, but multi-region ingestion adds questions:
- Where is the authoritative visit manifest?
- Can batches for one visit enter different regions?
- How is ordering preserved?
- When is a visit searchable?
- Where are encryption keys managed?
- How is deletion propagated?
- What happens during a regional partition?
- Is data allowed to cross regions?
Do not add regions only because the recorder is globally distributed. Add them when latency, resilience, or data-location requirements justify the coordination cost.
Account for clock skew
Client timestamps are necessary for event timing, but browser clocks can be wrong or can change during a visit.
Store both:
- client event time;
- server receipt time.
Use sequence numbers for ordering within a batch or visit where possible. Do not use a client timestamp alone as proof that one distributed action occurred before another.
Storage architecture for replay data
A replay system usually benefits from separating large recording bytes from queryable metadata.
Object storage for compressed chunks
A recording can be stored as immutable chunks plus a manifest.
A chunk record may include:
- visit ID;
- sequence range;
- byte length;
- checksum;
- codec;
- event count;
- first and last timestamp;
- storage location;
- processing status.
Immutability simplifies retries and auditability. Instead of updating an existing object, write a new uniquely identified chunk and let the manifest point to the accepted sequence.
A session manifest
The manifest tells the player what to load. It may contain:
- visit metadata;
- recording format;
- ordered chunk list;
- codec;
- plugin versions;
- expected duration;
- known gaps;
- playback compatibility class;
- retention or deletion state.
A manifest can be cached, but cache invalidation must occur when a visit is deleted, expires, is reprocessed, or has its access policy changed.
Metadata database
Use the metadata database for fields people need to query and govern:
- project;
- environment;
- user;
- Company;
- visit start and end;
- grouped pages and product areas;
- release;
- browser and device;
- processing state;
- replay health;
- retention date;
- deletion status;
- recorder version.
Keep raw recording bodies outside metadata queries unless a measured workload supports another design.
Search index
A search index may improve compound filters and high-cardinality discovery. It also creates another copy of potentially identifying metadata.
Define:
- which fields are indexed;
- how quickly updates appear;
- how deletion is propagated;
- whether index snapshots contain deleted data;
- who can query the index;
- how tenant boundaries are enforced.
Do not index every captured text value. That increases privacy exposure, index size, deletion scope, and the chance that free text becomes discoverable outside its intended context.
Cache for replay manifests
A cache can reduce player startup latency, but its keys and values are part of the retention and authorization model.
Do not cache a broadly accessible signed URL longer than its intended authorization window. Prefer caching nonsecret manifest data behind application authorization.
Archive tiers
Older recordings may move to a lower-cost tier, but archival changes the user experience:
- restore delay;
- retrieval fees;
- minimum storage duration;
- less predictable replay startup;
- additional processing;
- deletion interactions.
Make the archive state visible in search results. Do not let a user click a normal replay button and discover only after a long wait that the recording requires restoration.
Versioning and lifecycle policies
Object versioning can help recover from unintended overwrites or deletion. It can also retain noncurrent versions and increase cost.
For versioned storage, the retention policy must address:
- current versions;
- noncurrent versions;
- delete markers;
- incomplete multipart uploads;
- replication;
- object locks or legal holds.
Amazon S3 documentation, for example, notes that lifecycle expiration of a current object does not automatically remove noncurrent versions in a versioned bucket. Verify equivalent behavior for the selected provider.
Encryption
Encryption at rest should cover:
- recording objects;
- metadata databases;
- search indexes;
- queues or streams;
- backups;
- local processing disks;
- secrets.
Encryption does not replace authorization. An application or employee with broad decryption and storage access can still expose recordings.
Capacity estimation: use formulas, not universal recording sizes
There is no reliable universal “megabytes per session” number.
Actual recording size depends on:
- page complexity;
- DOM mutation frequency;
- mouse-move and scroll sampling;
- visit duration;
- canvas capture;
- cross-origin iframe behavior;
- network capture;
- console capture;
- image, font, and stylesheet handling;
- masking and blocking;
- compression;
- batch size;
- custom plugins.
Measure representative production traffic after privacy rules are in place.
Recorded visits per day
Recorded visits per day =
eligible visits per day
× recording sampling rate
Sampling must be expressed as a decimal in the calculation. A 25% sampling rate is 0.25.
Average compressed recording size
Average compressed recording size =
average recorded duration
× measured compressed bytes per unit of time
This is a planning simplification. In production, size may not increase perfectly linearly because initial snapshots, long idle periods, high-mutation intervals, and compression behave differently.
Daily recording storage
Daily recording storage =
recorded visits per day
× average compressed recording size
Primary retained storage
Primary retained storage =
daily recording storage
× retention days
Effective retained storage
Effective retained storage =
primary retained storage
× full-copy replication or backup factor
A replication factor of 2 means two complete stored copies in this simplified model. Provider-specific replication, erasure coding, database overhead, object metadata, and minimum billable sizes may change the actual bill.
Monthly ingestion bandwidth
Monthly ingestion =
daily recording storage
× days in billing month
Add protocol overhead, failed uploads, and retries when measured.
Peak ingestion throughput
Peak recorded bytes per second =
peak simultaneously recording users
× average recorded bytes per user per second
Then apply an explicit safety margin:
Designed peak throughput =
peak recorded bytes per second
× burst and failure headroom factor
Chunks and object count
Chunks per visit =
average recorded duration in seconds
÷ target chunk duration in seconds
Round up when a partial final chunk is stored.
New recording objects per day =
recorded visits per day
× (chunks per visit + manifest objects per visit)
Object count affects request cost, listing behavior, lifecycle processing, replication, and deletion even when total bytes remain unchanged.
Ingestion request volume
Ingestion requests per day =
recorded visits per day
× (batch requests per visit + lifecycle requests per visit)
Lifecycle requests might include visit creation and finalization. Add retries and authentication calls according to the implementation.
Metadata volume
Logical metadata per visit =
visit row size
+ (chunk metadata row size × chunks per visit)
+ searchable and derived metadata
Retained logical metadata =
recorded visits per day
× logical metadata per visit
× retention days
Then apply a measured database overhead factor for indexes, row overhead, free space, write-ahead logs, replicas, and backups. Do not present that factor as universal.
Replay read volume
Monthly replay object reads =
replay views per month
× average objects loaded per replay
Monthly replay delivery =
replay views per month
× average bytes delivered per replay
Account for partial viewing, cache hit rate, archived data, retries, and any asset proxying.
Total cost of ownership
A self-hosted session replay cost model should include both infrastructure and people.
Annual session replay TCO =
compute
+ object storage
+ database and search index
+ queues or streams
+ network transfer
+ backups and disaster recovery
+ monitoring and logging
+ security tooling
+ engineering maintenance
+ on-call and incident response
+ privacy, compliance, and audit work
+ internal support
Infrastructure cost
Model each service with its actual billing dimensions.
Monthly object-storage cost =
stored capacity × storage rate
+ write operations × write-operation rate
+ read operations × read-operation rate
+ lifecycle and retrieval operations
+ replication charges
+ network transfer
Monthly processing cost =
always-on compute
+ autoscaled compute
+ background-worker compute
+ temporary processing storage
Monthly metadata cost =
database compute
+ provisioned or consumed I/O
+ database storage
+ replicas
+ backups
+ search infrastructure
+ cache infrastructure
Monthly queue cost =
published messages
+ consumed messages
+ retained bytes or throughput units
+ cross-region transfer
Use the current official pricing documentation for the selected provider and region. Record the pricing date and every assumption. Do not transfer a headline estimate from another architecture.
Engineering maintenance cost
Annual recurring engineering cost =
maintenance hours per month
× 12
× fully loaded engineering cost per hour
Include time for:
- SDK and recorder upgrades;
- browser regressions;
- replay-player upgrades;
- masking regressions;
- data migrations;
- dependency updates;
- security patches;
- capacity planning;
- restore tests;
- privacy review;
- deletion tooling;
- observability;
- developer environments;
- documentation.
Incident and on-call cost
Annual incident-response labor =
incident hours per year
× fully loaded responder cost per hour
That still omits the organizational cost of interruptions, delayed roadmap work, customer communication, postmortems, and maintaining a viable on-call rotation.
Privacy, security, and audit cost
Include:
- threat modeling;
- access reviews;
- penetration testing where appropriate;
- dependency and vulnerability management;
- employee-access controls;
- retention review;
- deletion verification;
- legal and privacy review;
- audit evidence;
- incident exercises;
- vendor or cloud assessment.
Support cost
Replay failures are often product-specific. A support request can involve:
- a blank player;
- an incomplete recording;
- an unsupported browser;
- a missing asset;
- unexpected masking;
- unmasked content;
- a long loading time;
- an incorrectly mapped User or Company;
- a deleted recording still visible in search.
Someone needs both product context and replay-pipeline diagnostics to investigate those reports.
Why infrastructure can be the smaller cost
At modest volume, object storage may be inexpensive relative to even a few engineering days per month.
At high volume, storage, requests, indexing, and network delivery can become material. The staffing cost does not disappear. It usually grows with the number of integrations, regions, privacy rules, users, incidents, and supported recording versions.
The relevant comparison is not:
managed subscription
versus
object-storage bill
It is:
managed service total cost
versus
self-hosted infrastructure
+ recurring engineering
+ security and privacy operations
+ support
+ operational risk
Worked capacity example for a fictional B2B SaaS product
The following example is illustrative. It is not a benchmark for rrweb, Hymetry, or session replay generally.
Assume a fictional B2B SaaS product with:
Illustration only
| Assumption | Illustrative value |
|---|---|
| Customer Companies | 950 |
| Monthly active Users | 18,000 |
| Active Users on a typical day | 4,000 |
| Eligible visits per active User per day | 1.4 |
| Recording sampling rate | 55% |
| Average recorded visit duration | 14 minutes |
| Hypothetical compressed recording rate | 180 KB per minute |
| Chunk duration | 15 seconds |
| Primary retention | 30 days |
| Full-copy factor | 2 |
| Peak active concurrent Users | 420 |
| Replay views per month | 20,000 |
The 180 KB per minute assumption is deliberately hypothetical. The team must replace it with a measured distribution from its own product after configuring masking, blocking, sampling, plugins, and compression.
For readability, the calculations use decimal KB, MB, and GB. A cloud provider may bill with different unit definitions.
1. Recorded visits per day
Eligible visits per day =
4,000 active Users
× 1.4 visits per User
= 5,600 visits
Recorded visits per day =
5,600
× 0.55
= 3,080 recorded visits
2. Average recording size
Average compressed recording size =
14 minutes
× 180 KB per minute
= 2,520 KB
= 2.52 MB
3. Daily and retained storage
Daily recording storage =
3,080
× 2.52 MB
= 7,761.6 MB
= 7.7616 GB
Primary retained storage =
7.7616 GB per day
× 30 days
= 232.848 GB
Effective retained storage with two full copies =
232.848 GB
× 2
= 465.696 GB
This simplified footprint excludes object metadata, temporary processing data, incomplete uploads, logs, database indexes, queue retention, and provider-specific replication overhead.
4. Monthly ingestion
For a 30-day billing month:
Monthly ingestion =
7.7616 GB
× 30
= 232.848 GB
Retries and protocol overhead would increase network and request volume without increasing the amount of unique recording content.
5. Peak ingestion throughput
At a 55% sample rate, the expected number of simultaneously recording Users at the stated peak is:
Peak recording Users =
420
× 0.55
= 231 Users
The hypothetical compressed rate per recording User is:
Recorded bytes per User per second =
180 KB per minute
÷ 60
= 3 KB per second
Therefore:
Peak recorded throughput =
231
× 3 KB per second
= 693 KB per second
If the team applies a 2× burst and failure-recovery margin:
Designed peak throughput =
693 KB per second
× 2
= 1,386 KB per second
≈ 1.39 MB per second
This is only a byte-throughput baseline. Request concurrency, decompression CPU, validation, queue publishing, and downstream writes also need load tests.
6. Chunk and object count
A 14-minute visit contains 840 seconds.
Chunks per visit =
840 seconds
÷ 15 seconds
= 56 chunks
With one manifest per visit:
Objects per visit =
56 chunks
+ 1 manifest
= 57 objects
New objects per day =
3,080
× 57
= 175,560 objects
Objects in a 30-day primary-retention window =
175,560
× 30
= 5,266,800 objects
This shows why chunk duration is an operational choice. Cutting the chunk duration in half would approximately double chunk-object and write-request counts while leaving the underlying recording bytes roughly similar.
7. Approximate ingestion requests
Assume:
- one request per 15-second chunk;
- one visit-start request;
- one visit-finalization request;
- no retries for the base calculation.
Requests per recorded visit =
56 batch requests
+ 2 lifecycle requests
= 58 requests
Ingestion requests per day =
3,080
× 58
= 178,640 requests
Ingestion requests per 30-day month =
178,640
× 30
= 5,359,200 requests
A 2% batch retry rate would add roughly 103,488 batch submissions per month in this example, before considering other retries.
8. Metadata volume
Assume an illustrative metadata model with:
- 2.5 KB per visit row;
- 0.4 KB per chunk row;
- 4 KB per visit for page, identity, processing, and searchable references.
Logical metadata per visit =
2.5 KB
+ (56 × 0.4 KB)
+ 4 KB
= 28.9 KB
Logical metadata per day =
3,080
× 28.9 KB
= 89.012 MB
Logical metadata for 30 days =
89.012 MB
× 30
= 2.67036 GB
If measured database and index overhead is 2.5×:
Estimated database footprint =
2.67036 GB
× 2.5
= 6.6759 GB
The 2.5× factor is another explicit assumption, not an industry constant. Measure table, index, write-ahead-log, replica, and backup growth in the selected database.
9. Replay reads and delivery
Assume 20,000 complete replay views per month and that each view loads one manifest plus all 56 chunks.
Object reads per month =
20,000
× 57
= 1,140,000 reads
Recording delivery per month =
20,000
× 2.52 MB
= 50,400 MB
= 50.4 GB
Actual delivery may be lower when users watch only part of a visit or when a cache serves repeated data. It may be higher because of retries, player prefetch, asset delivery, cache misses, and archived-data restoration.
10. Translate the capacity into a cost model
Let:
S₁= primary storage price per GB-month;S₂= secondary-copy storage price per GB-month;W= write-operation price;R= read-operation price;Q= queue price per request or message;E= network-delivery price per GB;D= monthly database, index, and cache cost;C= monthly compute cost;O= monthly observability and security-tooling cost;L= monthly engineering and operational labor.
Then:
Illustrative monthly TCO =
(232.848 × S₁)
+ (232.848 × S₂)
+ (5,266,800 × W)
+ (1,140,000 × R)
+ (5,359,200 × Q)
+ (50.4 × E)
+ D
+ C
+ O
+ L
Adjust the operation units to the provider’s billing model. Some providers quote operations per thousand, per million, per provisioned throughput unit, or as part of another service.
This formula still needs separate allowances for:
- backups;
- replication operations;
- database I/O;
- archive restoration;
- logging volume;
- security review;
- support;
- incidents;
- taxes;
- commitment discounts;
- multi-region transfer.
Sensitivity matters more than the single result
The example changes linearly when one major assumption changes:
- Moving from 55% sampling to 100% increases recording volume by approximately
1 ÷ 0.55, or 1.82 times. - Doubling average visit duration approximately doubles bytes, chunks, ingestion requests, and playback work.
- Doubling retention doubles the steady-state primary storage footprint.
- Doubling hypothetical bytes per minute doubles ingestion and storage but does not necessarily double object count.
- Halving chunk duration approximately doubles chunk count and many request counts without doubling recording bytes.
- A mutation-heavy workflow can exceed a simple time-based estimate even when visit duration is unchanged.
Run the model with p50, p90, and p99 recording sizes rather than relying only on an average. Long visits and unusually active pages can dominate capacity and player behavior.
Security responsibilities
Self-hosting can remove some exposure to a replay vendor’s infrastructure. It simultaneously creates direct exposure to the company’s own ingestion endpoints, storage, credentials, application, employees, and operating practices.
The security question becomes, “Can we operate this system safely?” rather than, “Is a vendor involved?”
Protect data in transit
Use TLS for:
- browser-to-ingestion traffic;
- service-to-service calls;
- queue and database connections;
- administrative interfaces;
- replay delivery.
Reject insecure transport. Manage certificates and renewal as an operational dependency.
Use project-scoped collection credentials
A browser credential should be limited to the intended project and write operation.
Plan for:
- rotation;
- revocation;
- origin or application restrictions where appropriate;
- rate limits;
- compromised-key response;
- separate development and production credentials.
Do not embed credentials that grant recording read access in client-side code.
Authenticate and authorize ingestion
Validate:
- project status;
- credential;
- origin policy where used;
- payload size;
- supported schema;
- supported compression;
- event limits;
- request freshness where relevant.
A syntactically valid replay batch is not automatically authorized.
Rate-limit by requests and resources
OWASP’s API Security guidance treats unrestricted resource consumption as a security risk. A replay endpoint should limit more than calls per second.
Consider:
- bytes per minute;
- events per batch;
- sessions per project;
- processing CPU;
- queue growth;
- object writes;
- decompression expansion;
- concurrent uploads.
Compressed payloads require limits on both compressed and expanded size.
Manage secrets centrally
Protect:
- database credentials;
- storage credentials;
- signing keys;
- encryption keys;
- API tokens;
- queue credentials;
- administrator session secrets.
Use narrowly scoped identities, rotation, audit history, and separate credentials by environment. Do not use one long-lived cloud administrator key throughout the pipeline.
Restrict object-storage access
Recording buckets or containers should not be public.
Use:
- private-by-default policies;
- least-privilege service roles;
- project or prefix restrictions where appropriate;
- explicit access logs;
- short-lived signed delivery;
- separation between write, processing, backup, and read roles;
- prevention of broad listing by ordinary application users.
A signed URL is a bearer capability until it expires. Keep its scope and lifetime narrow.
Authorize every replay view
Being able to search for a visit should not automatically grant permission to load its recording.
Validate authorization when:
- returning search results;
- opening a visit;
- issuing signed object access;
- loading a manifest;
- exporting or sharing a replay;
- accessing a restricted environment.
OWASP recommends least privilege, deny-by-default behavior, permission checks on every request, and tests for authorization logic.
Protect employee and administrator access
For the internal application, consider:
- SSO where supported by the chosen system;
- multifactor authentication;
- least-privilege roles;
- time-bounded elevated access;
- environment isolation;
- periodic access review;
- immediate offboarding;
- audit logs for replay access;
- restrictions on bulk export;
- controlled support access.
Do not claim that an application supports SSO or MFA unless its current implementation does. These are requirements for the selected operating model, not assumed Hymetry open-source features.
Separate environments
Development and staging often contain weaker access controls and synthetic or copied customer data.
Keep production recording storage and credentials separate from:
- local development;
- automated tests;
- staging;
- demonstrations;
- support sandboxes.
Do not copy production recordings into a developer environment without an explicit, reviewed process.
Maintain vulnerabilities and dependencies
The operated surface includes:
- the recorder;
- replay library;
- web framework;
- queue clients;
- database;
- object-storage SDK;
- compression libraries;
- observability agents;
- operating system;
- container images;
- reverse proxy.
Track advisories, update dependencies, scan artifacts, and test security-sensitive upgrades against replay compatibility.
Prepare for incidents
Create procedures for:
- leaked project credentials;
- publicly exposed objects;
- unauthorized replay access;
- an unmasked sensitive field;
- compromised administrator access;
- deletion failure;
- malware or dependency compromise;
- unexpected cross-region transfer;
- backup exposure.
NIST’s incident-response guidance places preparation, detection, response, and recovery within ongoing cybersecurity risk management. A replay-specific runbook should identify who can stop ingestion, revoke access, preserve evidence, notify stakeholders, and verify remediation.
Privacy responsibilities
Self-hosted collection does not make overcollection acceptable. A recorder running on infrastructure the company controls can still capture unnecessary, prohibited, or unexpectedly sensitive data.
Use the detailed session replay privacy checklist for capture configuration and review. At the architecture level, address the following responsibilities.
Mask or block before storage
Apply privacy controls as early as practical.
Review:
- password inputs;
- payment fields;
- API keys and tokens;
- customer notes;
- support conversations;
- document content;
- free-text fields;
- file names;
- identifiers;
- hidden DOM content;
- dynamically inserted fields.
Masking changes the captured value. Blocking can remove an element or area from recording. Route exclusion can prevent recording altogether. These controls have different privacy and analytical effects.
Exclude sensitive routes
Some pages may not justify replay at all, such as:
- password or credential management;
- payment entry;
- medical or financial details;
- internal administration;
- secret management;
- private customer notes;
- impersonation workflows.
An excluded route is often safer than trying to enumerate every sensitive selector on that page.
Review URLs
URLs can contain:
- email addresses;
- customer names;
- document names;
- tokens;
- query strings;
- search terms;
- account identifiers.
Normalize or remove sensitive segments and query parameters before storage. Do not assume that masking visible input elements protects URL data.
Treat network and console capture as separate risk decisions
Network request or console plugins can expose data that was never visible in the rendered page.
They may contain:
- request bodies;
- response bodies;
- headers;
- authorization tokens;
- stack traces;
- personal information;
- internal IDs;
- developer diagnostics.
Do not enable them merely because the recorder supports a plugin. Define an allowlist, redaction policy, volume model, and review process first.
Minimize retention
The ICO’s data-minimisation guidance recommends identifying the minimum personal data needed for the purpose. Its storage-limitation guidance states that retention depends on how long the data is needed for the specified purpose rather than one universal period.
Apply that principle operationally:
- define why replay is collected;
- define who uses it;
- set the shortest useful retention;
- use different retention by environment where necessary;
- review whether a long-lived aggregate metric can replace an old recording.
Legal obligations depend on jurisdiction, role, data, contracts, and purpose. Technical controls do not replace legal review.
Implement deletion by User and Company
In B2B SaaS, deletion may need to follow both levels:
- an individual User;
- a Company or account;
- a project;
- a workspace;
- a time range;
- an environment.
Identity changes make this harder. Preserve enough mapping to find the relevant recordings without retaining unnecessary identity data indefinitely.
Test privacy controls in production-like conditions
Masking tests should cover:
- server-rendered fields;
- client-rendered fields;
- reused components;
- shadow DOM where relevant;
- iframes;
- new releases;
- responsive layouts;
- translations;
- error states;
- browser autofill;
- copied content;
- dynamically added selectors.
A privacy rule that worked on last month’s DOM can fail after a component refactor.
Monitor privacy regressions
Useful signals include:
- newly captured route patterns;
- unexpected recording-size changes;
- increases in input events;
- failures in automated masking fixtures;
- unrecognized recorder policy versions;
- network or console plugin activation;
- recordings from excluded environments.
Do not log the sensitive value again while trying to detect it.
Search and discovery are part of the product
A stored recording has limited value when people cannot find the one connected to a question.
For a B2B product, useful metadata may include:
- project;
- environment;
- date and time;
- User;
- Company;
- product area;
- grouped page;
- normalized page;
- visit duration;
- visit outcome where explicitly defined;
- release or build;
- browser;
- device;
- error state;
- processing status;
- replay health.
Search design creates three costs.
Indexing cost
Every indexed field consumes storage, write work, backup capacity, and deletion work.
High-cardinality identifiers and compound filters should be tested against real query patterns.
Privacy cost
An index can make identifying metadata easier to discover and aggregate. Index only what is needed for an approved investigation purpose.
Do not index all captured DOM text, input values, console output, or network bodies as a shortcut to “better search.”
Identity-quality cost
Incorrect User or Company mapping can send an investigator to the wrong recording or expose another account’s data.
Validate tenant boundaries during ingestion, indexing, and authorization. Do not rely on a UI filter as the security boundary.
Hymetry’s product model connects Pages, Companies, Users, and visits so a team can move from an aggregate or account-level signal to session evidence. That connection illustrates why replay discovery is more than a timestamped list of recordings.
Replay performance
A player must turn stored events into a responsive investigation experience.
Load the manifest first
The initial request should provide enough information to decide:
- whether the recording exists;
- whether the viewer is authorized;
- whether it is archived;
- which format and player path are required;
- how many chunks exist;
- whether chunks are missing;
- how soon the first playable state can appear.
Do not download an entire long visit before showing any useful state when progressive playback is possible.
Prefetch carefully
Prefetching the next chunks can reduce pauses. Fetching every chunk immediately can waste bandwidth, memory, and object reads when the viewer watches only a small interval.
Tune prefetch using:
- observed playback speed;
- network latency;
- chunk size;
- seek behavior;
- archive state;
- memory budget.
Keep decompression and parsing from blocking the interface
Large compressed batches can create CPU and memory spikes in the browser.
Measure:
- decompression time;
- event parsing time;
- first-frame time;
- seek latency;
- memory growth;
- garbage collection;
- long-task duration.
Consider incremental decoding or worker-based processing when supported by the player architecture.
Support seeking
Seeking through a long visit may require:
- periodic snapshots;
- an event-time index;
- chunk-level time ranges;
- checkpoints;
- a bounded reconstruction window.
Without those structures, seeking can require replaying a large event history from the beginning.
Handle dropped chunks visibly
The player should know whether a gap exists. Options include:
- skip to the next available checkpoint;
- mark an unavailable interval;
- stop playback with a useful error;
- continue while showing that the result is partial.
Do not silently compress the timeline as though the missing interval never occurred.
Plan for very long visits
Long visits can dominate:
- storage;
- object count;
- player memory;
- seek time;
- support requests;
- archive restoration;
- retention exceptions.
Decide whether to:
- split visits after a maximum duration;
- pause capture during prolonged inactivity;
- cap recording length;
- retain only selected long visits;
- create periodic snapshots;
- use different policies for special workflows.
Define an asset policy
A replay can depend on stylesheets, images, fonts, or other assets that change or disappear after recording.
Possible policies include:
- accept that external assets may drift;
- preserve selected assets;
- proxy or snapshot approved resources;
- retain enough styling in recording events;
- show a warning when assets are unavailable.
Asset preservation increases storage, security, copyright, and deletion scope. Make it an explicit choice.
Treat archived playback differently
Archived recordings may require restoration before replay.
Expose:
- archive state;
- expected availability behavior;
- retrieval progress;
- cancellation;
- failure;
- temporary restored-copy retention.
Do not represent archived and immediately available recordings as identical.
Retention and deletion
Retention is a coordinated data workflow, not only a bucket setting.
Define retention at the right level
A system may need:
- workspace-level defaults;
- project-level retention;
- environment-specific rules;
- shorter retention for sensitive product areas;
- temporary incident holds;
- different aggregate-analytics retention.
Avoid an unlimited default merely because storage appears inexpensive.
Delete all active references
A complete deletion workflow may need to remove or invalidate:
- recording chunks;
- manifests;
- metadata rows;
- search documents;
- caches;
- derived page paths;
- exports;
- signed or shared links;
- processing retries;
- dead-letter messages.
A lifecycle rule that deletes the primary object does not automatically remove these references.
Coordinate versioned objects
If object versioning is enabled, delete or expire noncurrent versions according to policy.
A normal delete operation may create a delete marker while older object data remains stored. Test the exact semantics of the selected provider.
Address backups
Immediate deletion from every immutable backup may not be technically or operationally possible.
Define and document:
- backup retention;
- access restrictions;
- restoration procedures;
- how deleted data is prevented from returning to active systems after a restore;
- when expired backup copies disappear;
- how deletion requests are tracked across recovery events.
Obtain legal guidance for the applicable obligations rather than making the architecture itself the legal conclusion.
Handle legal or security holds
A hold can intentionally prevent deletion. It should be:
- authorized;
- scoped;
- time-bounded or reviewed;
- auditable;
- visible to the deletion workflow.
Object-lock settings can make data impossible to delete until a retention period expires. Test those controls before applying them to privacy-sensitive replay archives.
Verify deletion
Maintain a deletion ledger with:
- request scope;
- requester;
- authorization;
- affected identifiers;
- systems checked;
- completion state;
- exceptions;
- verification time.
Verification can sample object existence, database references, search results, cache state, and replay access without reproducing deleted content in logs.
Reliability and observability
Monitoring should follow the user-visible outcome: can an authorized person find and play the recording that the system claims to have?
Ingestion indicators
Monitor:
- client batch attempts where available;
- accepted batch rate;
- invalid batch rate;
- unauthorized batch rate;
- rate-limit responses;
- bytes accepted;
- duplicate batch rate;
- out-of-order batch rate;
- missing sequence ranges;
- processing failures;
- queue lag;
- dead-letter volume;
- storage-write errors.
Recording-quality indicators
Monitor:
- playable visit rate;
- incomplete visit rate;
- unsupported-format rate;
- first-batch loss;
- final-batch loss;
- recordings with missing chunks;
- recordings with impossible timestamps;
- zero-event recordings;
- extreme recording-size outliers.
Playback indicators
Monitor:
- manifest load success;
- first playable frame;
- chunk-load failures;
- decompression errors;
- player exceptions;
- seek failures;
- archived restore failures;
- authorization denials;
- memory-related failures;
- playback failure by recorder version and browser.
Governance indicators
Monitor:
- deletion backlog;
- deletion completion time;
- expired objects still referenced;
- masking-test failures;
- unrecognized capture-policy versions;
- privileged access;
- unusual replay-download volume;
- cross-project access failures;
- storage growth;
- cost trend;
- backup age;
- restore-test status.
Example service-level indicators
Do not adopt universal targets from this article. Define indicators first, collect a baseline, and set objectives from business need.
Durable batch rate =
batches durably queued or stored
÷ valid accepted batches
Playable visit rate =
visits that successfully load a representative replay
÷ visits marked playable
Incomplete visit rate =
visits with detected missing required ranges
÷ processed recorded visits
Replay first-frame latency =
time from authorized open request
to first usable replay frame
Deletion completion time =
time from authorized deletion request
to verified removal from active systems
Retention conformance rate =
expired visits with no active recording references
÷ expired visits evaluated
Google’s SRE guidance recommends defining service-level indicators around user-relevant behavior and warns against treating 100% as a practical universal objective. Alert on failures that require action rather than every internal fluctuation.
Use metrics, logs, and traces together. OpenTelemetry documents those as complementary observability signals. Correlate a visit, batch, processing job, object write, manifest request, and player error with opaque operational identifiers rather than sensitive captured content.
Managed, self-hosted, and hybrid replay compared
The right model depends on the layers a team wants to control and the responsibilities it can sustain.
| Consideration | Managed replay | Complete self-hosting | Hybrid architecture |
|---|---|---|---|
| Control | Provider controls much of the platform; customer controls configuration and use | Team controls the operated stack and policies | Control is divided by layer |
| Setup time | Usually fastest when the product fits | Infrastructure and operational setup required | Moderate; integration boundaries still need work |
| Maintenance | Provider maintains core service | Team maintains recorder, pipeline, storage, player, and application | Each party maintains assigned layers |
| Data location | Depends on provider regions and product options | Determined by the team’s infrastructure choices | Depends on which data crosses the boundary |
| Customization | Limited to supported configuration and APIs | High potential, with long-term maintenance cost | Targeted customization in selected layers |
| Cost predictability | Subscription or usage model may be easier to forecast | Infrastructure and staffing can vary with growth and incidents | Mixed managed and internal costs |
| Privacy responsibility | Customer remains responsible for capture purpose and configuration; provider operates part of processing | Team directly operates capture, storage, access, retention, and deletion | Responsibilities must be assigned explicitly |
| Upgrade responsibility | Provider generally manages backend and player upgrades; customer manages integration changes | Team owns recorder, player, schema, dependency, and migration upgrades | Split by layer and contract |
| On-call burden | Provider handles much of service operation; customer still handles integration and policy incidents | Team owns the complete operational path | Shared, with escalation boundaries required |
| Scalability | Provider is responsible within documented service limits | Team must design, test, and fund scaling | High-volume layers can be assigned selectively |
| Lock-in | Provider APIs, exports, and formats may create switching cost | Dependencies still exist in recorder formats, storage schemas, and internal code | Can reduce or relocate lock-in, not eliminate it |
| Integration | Supported integrations may be quick; custom needs may be constrained | Deep internal integration is possible | Internal control can focus on identity, storage, or analytics |
Self-hosting is not “no lock-in.” A team can become dependent on an event format, player version, custom plugins, cloud provider, database schema, or a small group of internal maintainers.
When self-hosting may be appropriate
Self-hosting is more plausible when several of these conditions are true:
- strict data-location or network-boundary requirements;
- existing platform engineering and security operations;
- significant volume with predictable workloads;
- a need for custom retention, deletion, identity, or internal integration;
- an organization-wide open-source strategy;
- replay is a core product capability rather than a supplementary tool;
- a need to inspect or modify the code;
- the ability to fund long-term maintenance;
- an owner for on-call, security, privacy, and upgrades;
- a clear recovery and migration strategy.
Control is valuable only when the organization can exercise it reliably.
When managed replay may be more appropriate
Managed replay may be a better fit when:
- the engineering team is small;
- replay is supplementary to the core product;
- volume is low or uncertain;
- rapid deployment matters;
- there is limited security or platform operations capacity;
- the team does not want to maintain a replay player;
- deletion, masking, and access operations cannot be staffed internally;
- the managed product’s regions, controls, exports, and contract meet the requirements;
- predictable vendor cost is preferable to variable infrastructure and labor.
A managed service does not remove the customer’s responsibility to configure capture appropriately, control employee access, and establish a lawful and proportionate use.
Hybrid options
A hybrid design can concentrate internal ownership where it provides the most value.
Self-hosted ingestion with managed processing
The company controls the collection endpoint and may apply early filtering before forwarding approved data.
Evaluate:
- whether the managed processor accepts the format;
- which identifiers leave the environment;
- retry behavior between systems;
- responsibility for deletion;
- end-to-end support boundaries.
Self-hosted storage with managed UI
The company retains recordings while a managed application provides search or playback.
This requires a secure access protocol and clear answers about whether the managed service can read raw recordings, cache them, or retain derived metadata.
Managed replay with private networking or regional storage
Some managed services may offer regional deployment, private connectivity, or customer-controlled storage. Availability is vendor-specific. Verify the current product and contract rather than assuming support.
Record only selected high-value visits
Sampling can focus replay on:
- onboarding;
- a new release;
- a high-value workflow;
- an error state;
- a consented research cohort;
- Companies or Users meeting an approved criterion.
Selection reduces volume but can bias the evidence. Document how a visit becomes eligible.
Internal structured analytics plus managed replay
A team can retain long-term aggregate analytics internally while using short-lived managed replay for visual evidence.
This can reduce replay retention without losing long-term product-adoption trends.
Short replay retention with long aggregate retention
A recording may be useful for a few days or weeks, while grouped-page, Company, User, and visit metrics remain useful longer.
Keep the two retention policies distinct. An aggregate record should not quietly retain raw captured values.
A decision framework
Use a sequence of explicit decisions rather than a generic scoring sheet.
1. Define why replay is needed
Name the investigations replay should support.
Examples:
- onboarding failures;
- a difficult workflow;
- production support;
- design research;
- release validation;
- session evidence behind an account-level signal.
Do not begin with “capture everything and decide later.”
2. Estimate eligible volume
Measure:
- visits;
- duration distribution;
- mutation-heavy routes;
- peak concurrency;
- candidate sampling;
- likely replay views;
- retention.
3. Establish privacy and data-location requirements
Identify:
- routes that must be excluded;
- values that must be masked or blocked;
- countries or regions;
- employee-access restrictions;
- deletion requirements;
- network and console policy;
- legal review owners.
4. Inventory existing platform capability
Ask whether the organization already operates:
- durable ingestion;
- queues;
- object storage;
- database backups;
- observability;
- secret management;
- SSO or access management;
- incident response;
- data deletion workflows.
A familiar cloud provider is not the same as an operated replay platform.
5. Calculate infrastructure and staffing cost
Use measured size distributions and the TCO model in this article.
Include staff time even when the work will initially be absorbed by an existing team.
6. Assess replay expertise
Determine who understands:
- browser recording;
- rrweb or the selected format;
- DOM reconstruction;
- compression;
- asset handling;
- player performance;
- privacy masking;
- legacy playback.
7. Define reliability expectations
Decide:
- how much recording loss is acceptable;
- how quickly a replay should load;
- how partial visits are represented;
- whether replay is required during an incident;
- recovery objectives;
- on-call coverage.
8. Define access and deletion requirements
Document:
- who can view which recordings;
- approval for sensitive access;
- audit needs;
- deletion by User, Company, project, and date;
- backup behavior;
- hold behavior.
9. Compare managed and hybrid options
Compare equivalent outcomes, not object storage against a complete vendor product.
Review:
- data path;
- retention;
- exports;
- regional options;
- access controls;
- support;
- contract;
- migration path;
- total cost.
10. Run a limited production pilot
Use selected routes, Companies, Users, or a small sampling rate.
Measure:
- bytes per minute;
- chunk distribution;
- ingestion failures;
- replay load time;
- player errors;
- operator effort;
- support questions;
- masking results.
11. Test failures and privacy regressions
Before broad rollout, simulate:
- duplicate batches;
- missing batches;
- queue delay;
- object-store failure;
- unsupported format;
- expired credential;
- player rollback;
- deletion;
- backup restoration;
- an unmasked test value;
- a very long visit.
12. Assign long-term ownership
Name owners for:
- recorder;
- ingestion;
- storage;
- metadata and search;
- player;
- access;
- privacy rules;
- deletion;
- incident response;
- upgrade policy;
- cost review.
Do not launch a self-hosted replay system with no team responsible after the original builder moves on.
Common mistakes
Assuming rrweb alone is a complete replay product
rrweb provides recording and replay libraries. A production platform still needs ingestion, storage, identity, search, authorization, governance, and operations.
Storing replay events without a metadata index
A bucket of sessions is not an investigation tool. Store only the metadata needed to find approved recordings, but design discovery from the beginning.
Underestimating long-visit storage
Averages hide the tail. Model p90 and p99 duration and recording size.
Ignoring peak ingestion
Daily bytes do not reveal burst concurrency, queue lag, retry storms, or processing CPU.
Failing to version recorder and player
Every recording needs enough version metadata to choose a compatible decoding and playback path.
Capturing canvas, network data, or console logs without capacity planning
These options can change byte volume, processing, security exposure, and privacy risk substantially.
Assuming self-hosting is automatically compliant
Infrastructure ownership does not establish legal basis, proportionality, transparency, minimisation, security, or correct retention.
Deleting objects but not indexes and backups
Lifecycle expiration is one step in a coordinated deletion process.
Providing broad object-storage access
Do not give ordinary viewers bucket credentials or unrestricted listing. Authorize at the application layer and issue narrowly scoped access.
Failing to test partial recordings
A plausible but incomplete replay can lead to a false conclusion. Test missing starts, middles, ends, and assets.
Retaining every recording indefinitely
Set retention from purpose and operational need. “Storage is cheap” is not a retention policy.
Measuring only infrastructure cost
Include engineering, security, privacy, support, migration, on-call, and opportunity cost.
Having no on-call owner
Queues, storage, databases, certificates, player releases, and privacy controls fail outside project-planning meetings.
Upgrading the recorder without legacy playback tests
A new recorder does not rewrite recordings already stored. Run retained compatibility fixtures before deployment.
Failing to monitor replay-load failures
An ingestion-success chart cannot show whether authorized users can load and play recordings.
How Hymetry combines open-source product analytics and session replay
Hymetry is account-centric product intelligence for B2B SaaS. Its model connects product behavior across Pages, Companies, Users, and Visits so teams can start with an adoption or account-level signal and inspect session evidence when deeper investigation is useful.
In Hymetry’s product model, a Visit is the session-level evidence layer: it provides ordered product movement, timing, event context, and recording evidence. Pages, Companies, Users, and Visits live in the same product model so a team can start with an account-level signal and inspect relevant session evidence instead of browsing an undifferentiated replay library.
The current Hymetry open-source README describes a self-hosted product analytics and session replay application with Pages, Companies, Users and session analytics, page-structure naming with a workspace-provided OpenAI key, and screen recording. It documents Docker Compose and Render deployment paths, PostgreSQL plus Redis and Celery configuration, and GNU AGPLv3-or-later licensing.
The reference architecture in this guide is not a description of the current Hymetry OSS recording pipeline. The current implementation stores rrweb event JSON in PostgreSQL and processes recording ingestion synchronously; it does not implement the object-storage chunks, signed object URLs, or replay search index shown as possible production layers above. Replay access is gated by login and workspace/project membership rather than per-recording authorization.
The current main branch is still under development and uses a consolidated fresh-install migration set. Its README says existing OSS databases are not supported and directs operators to create a new database rather than upgrade an older schema.
The open-source path does not remove the responsibilities described in this article. The organization running it manages its own deployment, storage, retention, updates, operations, privacy configuration, access, backups, and capacity. Review the current repository documentation and implementation before deciding whether it meets a production requirement.
Do not infer unlimited scale, zero operating cost, automatic compliance, infrastructure guarantees, or complete feature parity with hosted Hymetry.
For more context on the evidence layer, see Hymetry Visits.
Frequently asked questions
Is rrweb a complete self-hosted session replay platform?
No. rrweb provides libraries and components for recording and replaying web interactions. A production platform still needs collection, authentication, rate limiting, durable processing, storage, metadata, search, access control, privacy operations, deletion, observability, backups, and administration.
Is self-hosted session replay more private?
It can provide greater control over infrastructure, storage location, retention, and access. It does not automatically make capture proportionate or safe. A self-hosted recorder can still collect sensitive fields, URLs, network bodies, console output, or unnecessary routes. Privacy depends on capture policy, access control, retention, deletion, testing, and the applicable legal requirements.
Is self-hosted session replay cheaper?
Sometimes, but object storage alone is not the comparison. Calculate compute, storage, databases, indexes, queues, network delivery, backups, monitoring, security tooling, maintenance, on-call, privacy work, and support. At modest volume, recurring engineering time can exceed the direct infrastructure bill.
How much storage does session replay need?
Use measured production data. Storage depends on visit count, sampling, duration, page complexity, mutation frequency, capture options, compression, and retention. Calculate recorded visits per day multiplied by measured average compressed size, then model p90 and p99 recordings separately.
Can session replay data be stored in PostgreSQL?
PostgreSQL can store large values, including through its TOAST mechanism. Whether it should hold complete replay payloads depends on append volume, write-ahead logs, replication, backups, deletion, query isolation, and playback access patterns. Object storage for chunks plus relational metadata is common, but not universal.
How long should recordings be retained?
There is no universal period. Start with the purpose of collection and the shortest retention that supports it. Separate replay retention from aggregate-analytics retention. Apply project or environment differences only when justified and operationally enforceable.
What is the main compatibility risk?
A new recorder, player, plugin, schema, compression codec, or browser behavior may not work with older stored recordings. Version the recording envelope and retain fixtures from every supported format.
Can a hybrid replay architecture reduce operational work?
Yes. A team can self-host selected layers such as ingestion, identity, or storage while using managed processing or playback. The benefit depends on whether responsibility, security, deletion, support, and data movement are clearly defined.
What should a production pilot measure?
Measure recording-size distributions, ingestion retries, missing chunks, queue lag, player startup, playback errors, masking results, deletion completion, operator time, and support burden. Test deliberate failures before expanding capture.
Sources
rrweb
rrweb repository — record and replay the web
https://github.com/rrweb-io/rrwebrrweb Guide
https://github.com/rrweb-io/rrweb/blob/main/guide.mdrrweb: Optimize the Storage Size
https://github.com/rrweb-io/rrweb/blob/main/docs/recipes/optimize-storage.mdrrweb Plugin API
https://github.com/rrweb-io/rrweb/blob/main/docs/recipes/plugin-api.md
Browser delivery
MDN Web Docs: Navigator.sendBeacon()
https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeaconMDN Web Docs: Request.keepalive
https://developer.mozilla.org/en-US/docs/Web/API/Request/keepaliveW3C: Beacon specification
https://www.w3.org/TR/beacon/
Object storage, queues, and streaming
Amazon S3 Pricing
https://aws.amazon.com/s3/pricing/Amazon S3: Expiring objects
https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-expire-general-considerations.htmlAmazon S3: Retaining multiple versions of objects with S3 Versioning
https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.htmlAmazon S3: Using server-side encryption with Amazon S3 managed keys
https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingServerSideEncryption.htmlAmazon S3: Download and upload objects with presigned URLs
https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.htmlAmazon S3: Locking objects with Object Lock
https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.htmlAmazon S3: Transitioning objects using Lifecycle
https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-transition-general-considerations.htmlAmazon SQS: At-least-once delivery
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues-at-least-once-delivery.htmlAmazon SQS: Standard queues
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.htmlAmazon SQS: FIFO queue delivery logic
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues-understanding-logic.htmlApache Kafka documentation
https://kafka.apache.org/documentation/Apache Kafka: Design
https://kafka.apache.org/41/design/design/
Database and backup
PostgreSQL: TOAST
https://www.postgresql.org/docs/current/storage-toast.htmlPostgreSQL: Indexes
https://www.postgresql.org/docs/current/indexes.htmlPostgreSQL: Backup and Restore
https://www.postgresql.org/docs/current/backup.htmlPostgreSQL: Continuous Archiving and Point-in-Time Recovery
https://www.postgresql.org/docs/current/continuous-archiving.html
Security and incident response
OWASP API Security Top 10 — 2023
https://owasp.org/API-Security/editions/2023/en/0x11-t10/OWASP API4:2023 — Unrestricted Resource Consumption
https://owasp.org/API-Security/editions/2023/en/0xa4-unrestricted-resource-consumption/OWASP Authorization Cheat Sheet
https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.htmlOWASP Transport Layer Security Cheat Sheet
https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Security_Cheat_Sheet.htmlOWASP Secrets Management Cheat Sheet
https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.htmlOWASP Multifactor Authentication Cheat Sheet
https://cheatsheetseries.owasp.org/cheatsheets/Multifactor_Authentication_Cheat_Sheet.htmlNIST Cybersecurity Framework
https://www.nist.gov/cyberframeworkNIST SP 800-61 Revision 3: Incident Response Recommendations and Considerations for Cybersecurity Risk Management
https://csrc.nist.gov/pubs/sp/800/61/r3/final
Privacy and data protection
Information Commissioner’s Office: Data minimisation
https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/data-protection-principles/a-guide-to-the-data-protection-principles/data-minimisation/Information Commissioner’s Office: Storage limitation
https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/data-protection-principles/a-guide-to-the-data-protection-principles/storage-limitation/Information Commissioner’s Office: Security outcomes
https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/security/a-guide-to-data-security/security-outcomes/Information Commissioner’s Office: Data protection by design and by default
https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/accountability-and-governance/guide-to-accountability-and-governance/data-protection-by-design-and-by-default/European Data Protection Board: Guidelines 4/2019 on Article 25 — Data Protection by Design and by Default
https://www.edpb.europa.eu/documents/guideline/guidelines-42019-on-article-25-data-protection-by-design-and-by-default_en
Reliability and observability
Google SRE Workbook: Implementing SLOs
https://sre.google/workbook/implementing-slos/Google SRE Workbook: Alerting on SLOs
https://sre.google/workbook/alerting-on-slos/Google SRE Workbook: Monitoring
https://sre.google/workbook/monitoring/OpenTelemetry Documentation
https://opentelemetry.io/docs/OpenTelemetry: Observability Primer
https://opentelemetry.io/docs/concepts/observability-primer/
Hymetry
Hymetry open-source repository
https://github.com/Hymetry/HymetryHymetry open-source README
https://raw.githubusercontent.com/Hymetry/Hymetry/main/README.mdHymetry Visits
https://hymetry.com/product/visits/Hymetry Privacy Controls
https://hymetry.com/product/privacy-controls/Hymetry Pricing and Open Source
https://hymetry.com/pricing/- Hymetry OSS — recording and analytics models
https://github.com/Hymetry/Hymetry/blob/da90b398e6ed0069b1835d08314f7ac46c6ca8d8/apps/tracker/models.py - Hymetry OSS — recording ingestion and replay views
https://github.com/Hymetry/Hymetry/blob/da90b398e6ed0069b1835d08314f7ac46c6ca8d8/apps/tracker/views.py