Execution-history retention

The built-in retention job that deletes old terminal executions and their events — off by default, batched, and multi-replica safe via advisory locks.

Every task in a durable workflow is a persisted event row. Without retention, executions and execution_events grow without bound — the table sizes become a function of everything your deployment has ever run. Flux ships a server-side retention job (flux/retention.py) that deletes old terminal executions on a schedule.

It is off by default, so upgrades never silently remove history. Enable it in production:

[flux.retention]
enabled = true
retention_days = 30    # age (days since last event) before a terminal execution is deleted
sweep_interval = 3600  # seconds between sweeps
batch_size = 500       # executions deleted per transaction

Env vars: FLUX_RETENTION__ENABLED, FLUX_RETENTION__RETENTION_DAYS, FLUX_RETENTION__SWEEP_INTERVAL, FLUX_RETENTION__BATCH_SIZE.

What gets deleted

A sweep deletes executions that are:

Dependent rows go with the execution: its execution events, agent sessions, and approval requests are deleted explicitly in the same pass, so no orphans accumulate on backends that don’t enforce cascades.

How the sweep runs

Choosing retention_days

The trade is disk versus audit history. Questions to answer before shortening it:

Backups interact the obvious way: a restore resurrects rows the retention job had deleted, and the next sweep deletes them again. See Backups and restore.

What’s next