Retention settings and report
What the Drupal server stores per run, how to see it, and how the retention policy is declared.
Every workflow run leaves rows behind: a pipeline, a job per node, and — when the run came from a chat or the Playground — a session and its messages. FlowDrop declares what it keeps, measures it, and reports on it.
Nothing is deleted. There is no sweeper, no cron cleanup and no purge
command for the governed types. Both retention modes behave identically today;
delete is accepted so a later release can honour it without a configuration
migration. Setting a mode changes only what the report says.
Where the settings live
The policy is configuration on flowdrop.settings, under a retention group.
There is no administration page for it — read and write it like any other
configuration:
drush config:get flowdrop.settings retention
drush config:set flowdrop.settings retention.flowdrop_job.max_age 604800The group ships with the module and is stamped onto existing sites by
flowdrop_post_update_add_retention_settings(), which writes absent keys only,
so a value you already chose survives.
What each type declares
One block per governed entity type, each with a mode and one or two age
thresholds:
| Key | Default | What it governs |
|---|---|---|
retention.<type>.mode | off | off or delete. |
retention.<type>.max_age | 2592000 (30 days) | Age in seconds after which a success-like terminal row would become eligible. 0 means every such row. |
retention.<type>.failure_max_age | 31536000 (365 days) | The same for failure-like terminal rows. Normally longer: a failed run is the one you still want to read next quarter. |
<type> is one of flowdrop_session, flowdrop_pipeline, flowdrop_job,
flowdrop_session_message and state_checkpoint.
state_checkpoint carries no status field, so age is the only criterion there:
it takes mode and max_age, and has no failure_max_age.
Every type ships mode: off, and off is a supported, legitimate state — a
site that keeps every run forever is doing nothing wrong.
The two modes
off— keep everything.delete— accepted by the configuration schema and reserved for a later release. It validates, and today it behaves exactly asoff.
A third mode, slim, was accepted by an earlier alpha and has been withdrawn.
It is gone from the schema, and flowdrop_post_update_drop_slim_retention_mode()
rewrites a stored slim to off when you run drush updatedb. Run the update:
a site that still stores slim fails strict configuration validation, so
drush config:inspect and configuration imports both complain.
What is never eligible
Only terminal rows are ever counted as eligible. A row that is paused,
pending, running, idle, awaiting_input or interrupted is not terminal
and no setting makes it eligible.
Reading the report
drush flowdrop:retention:report # the cached report
drush flowdrop:retention:report --refresh # recompute every count and size firstThe alias is fd:retention:report. The command is read-only: it deletes
nothing, and since nothing else deletes anything either, this is the dry run.
Seven columns are shown by default:
| Column | Field | What it means |
|---|---|---|
| Type | type | The entity type id. |
| Mode | mode | The configured mode for that type. |
| Rows | rows | Total stored rows. |
| Size | bytes | Base table plus dedicated field tables, data and index length. Not measured off MySQL/MariaDB. |
| Oldest | oldest | Age of the oldest row, in whole days. |
| Eligible (ok) | eligible_success | Success-like terminal rows older than max_age. |
| Eligible (fail) | eligible_failure | Failure-like terminal rows older than failure_max_age. |
Five more are available through --fields: kind (whether FlowDrop governs the
type, another module's cron already sweeps it, or its lifetime is an expiry
stamp), excluded (rows held by a non-terminal status, which no policy could
ever match), reclaim (bytes pro-rated across the eligible share of rows),
policy (what already governs a store FlowDrop does not) and error (why a row
could not be measured).
drush flowdrop:retention:report --fields=type,kind,excluded,reclaim,policy
drush flowdrop:retention:report --format=jsonA structured format always carries every column as raw numbers — bytes, unix
timestamps, integer counts — so you can do arithmetic on them instead of parsing
198.7 MB back into bytes. A dash in the table means not measured, which is
not the same as zero.
The report also accounts for the stores FlowDrop does not govern — interrupts, workflow snapshots and memory records — so one place accounts for everything the module deletes. Those keep their own cron cleanups and TTL, and their eligibility follows that sweeper's own rules: a cancelled snapshot is never reported as reclaimable.
The status report line
Drupal's status report carries a FlowDrop data retention line. It is informational, never a warning, and it only ever reads the cached report — measuring scans every runtime table, which is never done while rendering a page.
Cron builds the report once a day, a read-only warm that measures and caches and
deletes nothing, and rebuilds it on the next run whenever the cache is empty. So
a cache rebuild costs one cron interval rather than a day. Until the first build
the line reads Not yet computed and names
drush flowdrop:retention:report --refresh.
This is an operational size-and-age report, not a GDPR erasure mechanism. It makes no claim about personal data and offers no subject-level deletion.