Skip to main content

Retention

How org-wide retention is configured — operator bounds in env vars and UI controls under Governance for chats, documents, audit logs, and ledger rows.

3 min read

Retention in Tale is the policy that deletes old data on a schedule — chats, documents, audit logs, workflow executions, token-usage ledger rows. The operator sets bounds (minimums and maximums) per category; each org's admin picks the actual retention window inside those bounds via Settings > Governance > Retention policy. The split exists so a hosting team can enforce compliance floors without micromanaging every tenant.

This page covers the operator surface. The admin-facing controls and the per-category descriptions live in Governance > Retention policy.

How the bounds work

Each retention category — chat threads, documents, customers, vendors, prompt templates, ledger rows, audit logs, workflow executions, workflow trigger logs, login attempts — has a min and a max. An org admin sets a value inside that window. Tightening the floor across an existing instance is a multi-step flow: operator proposes the new bound, every affected admin sees a banner, the change applies once accepted.

CategoryTypical floorWhy
Chat history30 dMost users want recent context, not forever
Documents1 yKnowledge tends to age out slowly
Audit logs1 y minimumCompliance frameworks expect a year
Token-usage ledger90 dAnalytics and budget reports rely on rows
Workflow execution logs30 dDebugging rarely reaches further back
Login attempts30 dBrute-force investigation needs the audit tail

The shipped defaults are loose; tighten per your compliance posture.

Where you set bounds

Under the org-first layout, retention bounds are per-org: edit retention.json directly inside an org's subtree under TALE_CONFIG_DIR (defaults to /app/data/ inside the platform container, so the file lives at /app/data/<org>/retention.json, e.g. /app/data/default/retention.json). Each org has its own file; the default org's file is the template a fresh deployment picks up on first boot.

json
{
  "chatHistory": { "min": 30, "max": 730, "unit": "days" },
  "documents": { "min": 1, "max": 3650, "unit": "days" },
  "auditLog": { "min": 365, "max": 3650, "unit": "days" },
  "tokenLedger": { "min": 90, "max": 1095, "unit": "days" }
}

The platform container watches the file; changes propose a bounds update for every existing org. Admins see the proposal in their Retention policy screen and apply it themselves. The propose-then-apply step is deliberate: tightening a floor shortens history, which is a destructive action no operator should land silently on every tenant.

The retention sweep

A scheduled cron inside tale-convex runs the actual deletion. Each category is swept independently — a slow run on one does not block the others. Deletions are audited (every category has its own *.retention_deleted event), and restoring an entity inside its grace window is possible from Trash before the final sweep.

Audit log entries are themselves subject to retention, but their floor is enforced per-deployment, not per-org: the strictest (shortest) audit-log retention across all orgs is what actually runs. A stricter tenant pulls everyone tighter — keep this in mind on multi-tenant instances.

A legal hold freezes retention for a specific scope: a single thread, a customer record, or an entire organization. Held entities skip the sweep until the hold is released. The hold itself is audited; org-wide holds are loud enough that the UI surfaces a confirmation before they apply.

Where this fits

The bounds file is the operator's lever; the per-category windows the admin sees are documented in Retention policy. If you are setting bounds against a compliance framework (GDPR, HIPAA, SOC 2), the audit-log floor is usually what auditors check first.

© 2026 Tale by Ruler GmbH — ISO 27001 & SOC 2 certified.

Tale is MIT licensed — free to use, modify, and distribute.