Storage and your data
Recordings are plain gzipped JSON files in your bucket. Everything else is in a handful of database tables. Both are yours to back up, export or delete.
Object storage
S3 has no append operation, so every upload from the recorder becomes its own object:
| Key | Contents |
|---|---|
sessions/<session>/parts/<first-timestamp>-<page>-<seq>.json.gz |
One batch of events, gzipped |
If you set S3_PREFIX, it is added in front of every key. A batch the recorder retried overwrites the same object.
Database
D1 and Postgres use the same schema:
| Table | Contents |
|---|---|
sessions |
One row per session: start, end, duration, first and last URL, page views, user agent, device, viewport, and counts of events, clicks, rage clicks, errors and inputs |
session_pages |
One row per page view: session, time, host, path and full URL |
session_users |
The user IDs attached to each session |
batches |
One row per uploaded batch, used to ignore retries and to detect rage clicks that span two batches |
settings |
The admin password hash and cookie signing secret |
Exporting
There is no lock-in format. To export a session, copy its folder under sessions/ from the bucket and its rows from the database. To export everything, back up the bucket and the database with the tools you already use.
Deleting
Delete a session from the dashboard or with DELETE /api/sessions/:id. This removes its recordings and its rows. There is no automatic retention limit yet; to keep only recent data, use your bucket’s lifecycle rules together with a scheduled query that removes old rows.