Retention
The Botfather tower stores fleet telemetry — heartbeats, cost rollups, alerts, and activity. A daily retention job trims this data so the database doesn't grow without bound.
The retention job
Once a day, the tower runs a retention sweep that deletes telemetry older than its window. Different data classes have different windows — long-lived rollups are kept longer than high-volume raw events.
Retention windows
| Data class | Retention window | Notes |
|---|---|---|
Cost facts (cost_facts) | 13 months | Per-run cost events received from instances |
Run facts (run_facts) | 90 days | Per-run execution records |
Activity facts (activity_facts) | 12 months | Agent and squad activity events |
Resolved alerts (alerts) | 90 days | Only rows where status = 'resolved' |
| Rollups | Indefinitely | Hourly and daily aggregates; not trimmed |
The job runs every 24 hours via setInterval. It is not configurable at runtime — all windows are compile-time constants in server/src/services/retention.ts.
What is retained
The tower only ever holds metadata and metrics — never issue bodies, logs, or adapter configuration (see What is and isn't synced). Retention therefore applies to:
- Heartbeat and sync records
- Cost-event rollups and forecasts
- Alert history (after auto-resolve)
- Fleet activity
Backups
Retention trims live data; it is not a backup strategy. If you need long-term history beyond the retention window, export or back up the tower's PostgreSQL database (see Self-Hosting) on your own schedule.
Next steps
- Self-Hosting — database and deployment
- Cost Analytics — what the rollups feed
- What is and isn't synced — the data boundary