Data retention and export
Railhook keeps every event, attempt and incoming event, and retention is the only thing that stops those tables growing. This page shows what is kept and for how long, and how to answer an export or erasure request.
What is kept, and for how long
Section titled “What is kept, and for how long”Set these in .env. The defaults keep a self-hosted deployment from growing without bound.
| Data | Variable | Default |
|---|---|---|
| Failed attempts | DATA_RETENTION_ATTEMPTS_DAYS |
90 days |
| Successful (2xx) attempts | DATA_RETENTION_SUCCESSFUL_ATTEMPTS_DAYS |
14 days |
| Events | DATA_RETENTION_EVENTS_DAYS |
90 days |
| Incoming events | DATA_RETENTION_INCOMING_EVENTS_DAYS |
30 days |
| Attempts kept per delivery | DATA_RETENTION_MAX_ATTEMPTS_PER_DELIVERY |
10 |
| Abandoned outbox rows | OUTBOX_DEAD_RETENTION_DAYS |
90 days |
| Tunnel request log | — | 7 days |
Why the defaults look like this:
- Successful attempts go first. A 2xx attempt tells you little once you know it worked; a failed one is the debugging record. Removing successes at 14 days removes most of the volume and keeps the evidence.
- Events and failed attempts share 90 days. Keeping attempts longer than their event leaves records that point at nothing.
- A cap per delivery catches what age cannot: an endpoint that fails for a week keeps adding attempts to the same delivery.
When cleanup runs
Section titled “When cleanup runs”| Job | Default schedule | Variable |
|---|---|---|
| Main cleanup | 02:00 daily | DATA_RETENTION_CRON |
| Attempts-per-delivery cap | Every 30 minutes | DATA_RETENTION_LIMIT_CRON |
| Burst cleanup | Every 4 hours | DATA_RETENTION_BURST_CLEANUP_CRON |
| Table size metrics | Every 15 minutes | DATA_RETENTION_TABLE_METRICS_INTERVAL_MS |
Rows are deleted in batches of DATA_RETENTION_BATCH_SIZE (default 1000), so a long-overdue first run does not lock the platform.
Delivery attempts and the tunnel request log are partitioned by time in Postgres. For those tables an expired period is removed by dropping its whole partition, which is instant, instead of deleting rows one by one. PARTITION_MAINTENANCE_ENABLED (default true) creates partitions ahead of time and drops expired ones.
Check that cleanup is working
Section titled “Check that cleanup is working”| Metric | Meaning |
|---|---|
delivery_attempts_table_rows, events_table_rows, incoming_events_table_rows |
Estimated rows in each large table |
delivery_attempts_cleanup_total, events_cleanup_total, incoming_events_cleanup_total |
Rows removed |
partition_dropped_total |
Partitions dropped |
partition_default_rows |
Rows that landed in the default partition. Should be zero; anything else means a partition was missing. |
If a table keeps growing while its cleanup counter stays flat, the job is not running. Check the cron values and the API logs around 02:00.
Export an organization
Section titled “Export an organization”An owner can export an organization with GET /api/v1/orgs/{orgId}/export. The export is one JSON document with the organization’s configuration and audit history: the organization, members, projects, endpoints, subscriptions, sources, destinations, API keys and audit entries.
- Payloads are not included. Events, deliveries and attempts are too large to assemble into one document. Say so to anyone answering a subject-access request with this file.
- Audit entries are capped at 10,000. When the cap applies,
auditLogsTruncatedistrueandauditLogsTotalgives the real count.
Erase data
Section titled “Erase data”A whole organization. An owner deletes it with DELETE /api/v1/orgs/{orgId}, which removes everything that belongs to it. The audit log is kept on purpose, so the erasure can be shown to have happened.
One person’s account. The person deletes it with DELETE /api/v1/auth/me:
- Identifying data is replaced and the account can never sign in again. Every session is closed and every membership removed.
- An organization where they were the only member is deleted with them.
- The request answers
409if they are the last owner of an organization other people still belong to. Ownership has to be handed over first.
Both erasures and the export are recorded in the audit log.