yeke.io · docs
Retention and Archive
Retention settings control when expired records are deleted and are available on every tier. With Enterprise and PostgreSQL, you can archive those records before deletion.
Retention periods
Run in every tier including Community: item for item, unchanged.
A sweeper deletes expired records on a regular schedule. The period is set with three separate environment variables, each covering a different class of data:
| Variable | Default | Scope |
|---|---|---|
YEKE_OPS_RETENTION_DAYS | 90 days | Sweeps three tables at once: operation records, sessions, and the hook delivery queue (delivered/dead rows only). |
YEKE_CHAT_RETENTION_DAYS | 30 days | Chat sessions and messages: deliberately shorter than operation retention, since chat carries far more free-form text than a plan does. |
YEKE_AI_EGRESS_RETENTION_DAYS | 365 days | AI egress log, deliberately longer than chat: "where did this cluster's data go, and when" should still be answerable after that conversation is gone. |
In SQLite mode there is also a cap of 1000 operation records per cluster — it runs independently of the time period and keeps the single-file database from growing unbounded. In PostgreSQL mode this cap does not run; size management is your DBA's discipline.
The audit trail is out of scope
Deleting a record doesn't mean it silently disappears.
These three periods do not apply to operation_events. The audit trail is append-only and is not removed by retention cleanup. It retains who acted, when and under which identity, even after the operation record is deleted.
What archiving is
The Enterprise retention-archive feature, PostgreSQL mode only.
When YEKE_RETENTION_ARCHIVE=1 is set, operation rows whose retention period has
expired are copied to an archived_operations table in the same database before
they're deleted. That table is monthly-partitioned by deleted_at — your own
DBA can move old months elsewhere or drop them with DETACH PARTITION.
Deletion and archiving happen in a single transaction: if the archive write fails, the delete does not happen either, and it's retried on the next sweep. There is no structural path to a silent data loss.
In SQLite mode this env var is an explicit error
If YEKE_DB_URL is unset (i.e. you're on SQLite), setting
YEKE_RETENTION_ARCHIVE=1 stops core at startup — it is not silently
ignored. Archiving into the same file would undo exactly what the 1000-record cap protects
(file size).
What the archive covers
Only the operations table; every other class was weighed individually.
An archived row is the plan body (plan_json), redaction paths, snapshot
envelope, and status/timestamp fields as they stood at the moment of deletion. Every other
class of data the sweeper deletes is not archived:
- Sessions. Identity events already live in the audit trail, and that trail is never deleted.
- Chat sessions and messages. The short retention period is a deliberate privacy decision — chat carries free-form text; archiving it would contradict that decision.
- AI egress log, hook delivery queue. Their own persistence claims already live in their own fields or in the audit trail.
Reading it back
An API endpoint, not a screen, in this release.
Archived records are read through GET /api/archive/operations (admin +
retention-archive): filtered by clusterId and time range, paginated,
read-only. There is no UI screen for this in this release — the endpoint exists so a compliance
question like "what was applied to this cluster last year" can be answered from the API.
snapshots_enc stays an envelope in the archive too; opening it needs your
installation's own snapshot key.
Auditability of deletion
Even a record's disappearance shows up in the trail, Community included.
Each cleanup pass writes one retention.swept summary per table type, including the deleted row count, date range and archived row count when archiving is enabled. It does not create an event for every deleted row.
This event is written in every tier, Community included; reading the trail is free in every tier, and "what got deleted" is part of that reading. Even when a license is frozen, archiving keeps running: continuing to delete without archiving while frozen would cause data loss, and the person it would punish is the customer's own auditor.
Limits
Archiving exists in one mode only; the other keeps today's behavior exactly.
- Archiving only works in PostgreSQL mode. In SQLite mode, today's behavior (time-based deletion + the 1000-record cap) does not change at all.
- Scope is operation records only. Chat, AI egress, and session data are not archived; they're deleted on their own schedules.
- Read-back is API-only in this release. There is no UI screen for the archive.
- Total disk management is your organization's job. Deletion with archiving on doesn't free space in the short term — the old row is deleted and a new one written to the archive, so it occupies space twice until the next autovacuum pass.
Archiving's prerequisite is PostgreSQL
Archiving shares the same database connection as HA. The connection shape and license gate are on the PostgreSQL page.