retention on an entity and Pylon deletes rows once they pass
the retention period. A system job runs every hour. Each row is deleted
through the same path as an entity-API delete: plugin hooks run, sync
clients receive the delete, and CRDT and search data for the row are
removed. Each deletion is recorded in the audit log
as retention.delete.
A fixed period
createdAt is more than 365 days old. Durations
use s, m, h, d, w, or y (365 days).
A period per tenant
Leave outafter. field is then the expiry time itself, and a row is
deleted once it is in the past. Set it on each row from the tenant’s
setting:
deleteAfter on its existing
rows.
Legal hold
hold names a bool field. Rows where it is true are kept, however
old they are. Clear the field to release the hold; the next sweep
deletes the row if it has expired.
Rules
fieldis adatetimefield, or anint/floatfield holding unix milliseconds.holdmust be aboolfield.- A missing field, a wrong type, or an unparsable duration fails boot
with
RETENTION_MANIFEST_INVALID. - Datetime values are compared as stored. Store UTC ISO-8601 strings
(
new Date().toISOString()) on SQLite.
Run a sweep now
held counts expired rows kept by a hold. failed counts deletes that
failed; they are retried on the next sweep and logged. unaudited
counts rows deleted whose audit record could not be stored (logged). On Postgres, one
replica runs each scheduled sweep.
Retention deletes the row only. Files in storage that a row points to
(url above) are not deleted; remove them from a before_delete plugin
hook or a scheduled function.