Skip to main content
Declare 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

A row is deleted once createdAt is more than 365 days old. Durations use s, m, h, d, w, or y (365 days).

A period per tenant

Leave out after. 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:
When a tenant shortens its period, update deleteAfter on its existing rows. 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

  • field is a datetime field, or an int/float field holding unix milliseconds.
  • hold must be a bool field.
  • 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.