Data retention¶
A scheduled cleanup deletes rows that have expired, so the database does not keep sign-in data longer than it
needs to. It is on by default (added in 1.0.0-rc.13). It runs every 15 minutes in batches of 500 rows with
FOR UPDATE SKIP LOCKED, so it is safe with several replicas.
What is deleted¶
| Data | Deleted |
|---|---|
| OAuth2 authorizations | one hour after their last token expired (the refresh token included); abandoned ones (no token yet, e.g. a consent or PAR request never finished) after a day |
| Browser sessions kept in PostgreSQL | after they expire (5-minute grace) |
| One-time codes | when older than two days |
| Magic-link, e-mail-verification and e-mail-change tokens | a day after they expired |
| Audit log | never by default; only when helix.retention.audit-log-max-age is set |
Flow state, rate limits and wallet transactions have their own sweepers (see High availability).
The audit log is a policy decision¶
How long to keep the audit log depends on your logging, archiving and supervisory obligations, so HelixIAM keeps it until you set a maximum age. Decide that first, and ship the audit log to your SIEM or archive if it must outlive the database rows (see Events & audit).
Settings¶
| Property | Environment variable | Default |
|---|---|---|
helix.retention.enabled |
HELIX_RETENTION_ENABLED |
true |
helix.retention.interval |
HELIX_RETENTION_INTERVAL |
15m |
helix.retention.batch-size |
HELIX_RETENTION_BATCH_SIZE |
500 |
helix.retention.max-batches-per-run |
HELIX_RETENTION_MAX_BATCHES_PER_RUN |
200 |
helix.retention.authorization-grace |
HELIX_RETENTION_AUTHORIZATION_GRACE |
1h |
helix.retention.authorization-unfinished |
HELIX_RETENTION_AUTHORIZATION_UNFINISHED |
1d |
helix.retention.session-grace |
HELIX_RETENTION_SESSION_GRACE |
5m |
helix.retention.code-max-age |
HELIX_RETENTION_CODE_MAX_AGE |
2d |
helix.retention.token-grace |
HELIX_RETENTION_TOKEN_GRACE |
1d |
helix.retention.audit-log-max-age |
HELIX_RETENTION_AUDIT_LOG_MAX_AGE |
empty: keep the audit log |
Durations use Spring's format (30m, 12h, 400d). In the Helm chart: retention.enabled, retention.interval
and retention.auditLogMaxAge.
helm upgrade --install helixiam oci://ghcr.io/melmarzgioui/helixiam/charts/helixiam --version 1.1.0-rc.4 ... --set retention.auditLogMaxAge=400d
Metrics¶
helix_retention_deleted_rows_total{table} counts deleted rows per table and helix_retention_run_seconds times
each run; both are on /actuator/prometheus (see Observability & health).
See also¶
- GDPR & privacy: exporting and erasing one user's data
- Backup & disaster recovery: deleted rows stay in older backups until those expire