12. History and archive
Stores and lifetimes
| Store | Contents | Service | Lifetime |
|---|---|---|---|
| Live state | What a run needs to continue: task statuses, timers, awaited events | Durable Task Scheduler | Until the run ends, then purged after 7 days |
| History | One row per run and per task; logs; event executions; poll data | Azure SQL | 13 months by default, settable per workflow name |
| Payloads | Inputs and outputs above the size threshold | Blob | Same as history |
| Archive | Finished runs past retention, one JSON file each | Blob, cool tier, archive tier after 12 months | Indefinite |
Every read by the API or the UI goes to Azure SQL or the archive. Nothing reads live state directly.
History tables
workflow_run (workflow_id, name, version, status, correlation_id, priority, input, output,
variables_json, started_at, ended_at, reason, parent_workflow_id, parent_task_id,
owner, instruction_versions_json, idempotency_key, retry_of, restart_of, rerun_of)
task_run (task_id, workflow_id, task_ref, task_type, task_def_name, status, attempt, worker_id,
domain, scheduled_at, started_at, ended_at, input, output, reason,
callback_after_s, poll_count, queue_wait_ms)
task_log (id, task_id, logged_at, line)
poll_data (task_type, domain, worker_id, last_poll_at)
event_execution (id, handler_name, source, message_id, status, action, result_json, at)
workflow_message(workflow_id, seq, payload_json, pushed_at, pulled_at)
task_cache (key, output_json, expires_at)
The engine writes workflow_run at start and end, and task_run at every status change. Task logs are capped at 100 lines per task.
Search
Indexes: (name, status, started_at), (correlation_id), (status, ended_at), and a full-text index on reason. GET /api/workflow/search and GET /api/tasks/search use them. Analytics over history runs on the Fabric mirror of these tables, never on the API.
Redaction
maskedFieldsin a definition lists input and output paths to redact before writing.- Values from
${workflow.secrets.*}are resolved at the moment of use and never written to history or logs.
Archival
A daily function selects runs with a terminal status older than the retention period, writes each run with its tasks and logs to archive/{yyyy}/{mm}/{workflow_id}.json, and deletes the rows. GET /api/workflow/{id} reads Azure SQL first and the archive second, so an archived run is still readable.