Log Retention
Voodflow records detailed execution logs for every workflow run. This page covers the retention model, configuration options, and strategies for long-term compliance with legal and regulatory requirements (GDPR, ISO 27001, sector-specific legislation).
What Gets Logged
Every workflow execution creates a VoodflowExecution record and a set of VoodflowExecutionNode child records. For a full schema reference, see Executions.
Data Stored per Execution
| Data | Location | Contains |
|---|---|---|
| Execution record | voodflow_executions | Trigger type, status, timestamps, duration, error message |
| Per-node records | voodflow_execution_nodes | Node type, input snapshot, output snapshot, duration, error |
| Log entries | voodflow_execution_logs | Timestamped log lines, level (info/warning/error), message |
| Trigger payload | Inside execution record | The raw data that started the workflow |
What is NOT Logged
- Credential values (API keys, passwords, tokens) are never written to the execution log
- Binary data is truncated or omitted
- Only the first N bytes of large payloads are persisted (configurable)
Configuration
Retention settings live in config/voodflow.php:
'execution' => [
// Maximum number of days to retain execution records.
// null = retain forever (not recommended for production)
'retention_days' => env('VOODFLOW_RETENTION_DAYS', 90),
// Maximum bytes of input/output payload to store per node.
// Larger payloads are truncated.
'max_payload_bytes' => env('VOODFLOW_MAX_PAYLOAD_BYTES', 65536),
// Whether to log the full payload or only a summary
'log_payload' => env('VOODFLOW_LOG_PAYLOAD', true),
],Automated Cleanup
Voodflow ships with an Artisan command to prune old execution records:
php artisan voodflow:prune-executionsBy default, this deletes all VoodflowExecution records older than retention_days days (as configured above), along with their related VoodflowExecutionNode and VoodflowExecutionLog records (cascaded via foreign key constraints).
Running on a Schedule
Add the pruning command to your Laravel console kernel (app/Console/Kernel.php):
protected function schedule(Schedule $schedule): void
{
// Run every day at 02:00 AM
$schedule->command('voodflow:prune-executions')->dailyAt('02:00');
}Dry Run
Preview which records will be deleted without deleting them:
php artisan voodflow:prune-executions --dry-runCustom Retention Window
Override the retention days at invocation time:
php artisan voodflow:prune-executions --days=30Per-Workflow Retention Override
Individual workflows can override the global retention period. In the workflow settings panel:
| Setting | Description |
|---|---|
retention_days | Number of days to retain executions for this workflow |
retain_on_failure | If true, failed executions are never pruned regardless of age |
legal_hold | If true, the workflow is exempted from all automated pruning |
Legal Hold
Workflows processing data subject to regulatory hold (litigation, audit, tax obligations) should have legal_hold enabled. When active:
- The
voodflow:prune-executionscommand skips all executions belonging to that workflow - Manual deletion is still possible via the admin UI with a dedicated permission (
voodflow.executions.force-delete) - The hold state is logged with a timestamp in the workflow's audit trail
// Programmatically enable legal hold on a workflow
$workflow = VoodflowWorkflow::find($id);
$workflow->update(['legal_hold' => true]);GDPR Compliance
Under GDPR, you may need to:
- Minimize data — Disable
log_payloador reducemax_payload_bytesfor workflows processing personal data - Honor erasure requests — Provide a mechanism to delete executions containing a specific user's data; use the
voodflow:prune-executions --workflow=<id>flag or delete via Eloquent - Document retention — Set
retention_daysto a value consistent with your privacy policy (e.g. 90 or 180 days) - Log access — The Credentials system logs access events; execution logs are themselves an audit trail
Pseudonymization Strategy
For workflows that process PII (names, emails, phone numbers), consider transforming sensitive fields upstream with a PHP Code node before they reach any node that stores output:
return [
'user_id' => $input['user_id'], // keep identifier
'email_hash' => hash('sha256', $input['email']), // hash PII
'country' => $input['country'], // non-identifying
// 'email' intentionally excluded
];Retention Strategies by Use Case
| Use Case | Recommended retention_days | Notes |
|---|---|---|
| Development / testing | 7 | Short; high volume of test runs |
| Operational automation | 90 | Sufficient for operational review |
| Financial / billing | 365–2555 | Match accounting retention requirements |
| Healthcare / medical | 3650 (10 years) | Verify local legislation |
| Legal hold / litigation | legal_hold = true | Indefinite until hold is released |
| GDPR personal data | 30–90 | Align with privacy policy |
Storage Impact
Estimate storage growth:
| Per-execution record size | ≈ 1–5 KB (metadata only) |
|---|---|
| Per-node record size | ≈ 1–50 KB depending on max_payload_bytes |
| Per-log-entry size | ≈ 200–500 bytes |
| Typical execution (10 nodes, small payloads) | ≈ 100–200 KB |
For high-frequency workflows (e.g. a webhook that fires 1000 times/day), calculate:
$$\text{storage per month} = \text{executions/day} \times 30 \times \text{avg execution size}$$
At 1000 executions/day × 100 KB × 30 days = 3 GB/month before pruning.
Tune retention_days and max_payload_bytes accordingly.
Database Partitioning (Advanced)
For very high-volume deployments, consider partitioning the voodflow_executions table by month using a database-level range partition. This makes pruning a metadata operation (dropping a partition) rather than a row-level DELETE, improving performance by orders of magnitude.
This is a database-level concern and must be implemented at the MySQL/PostgreSQL level; Voodflow's migrations do not add partitioning by default.
Notes
- The pruning command wraps deletions in batches to avoid long-running transactions; it is safe to run on a live system
- Execution records are soft-deleted if the
VoodflowExecutionmodel usesSoftDeletes; add--forceto permanently delete - Audit logs of who accessed the Voodflow admin panel are handled by Filament Shield and are separate from execution logs