For the complete documentation index, see llms.txt. This page is also available as Markdown.

Retention

Configure release-backed retention policies that remove workflow instances and their related runtime records.

The Elsa.Retention extension runs a recurring, server-side cleanup job. A policy selects workflow instances with a RetentionWorkflowInstanceFilter, then the default deletion strategies remove the matching instance and its related bookmarks, activity execution records, and workflow execution logs. Retention is destructive: it is not an archive, backup, or preview feature.

Use it when you have an explicit data-lifecycle policy for completed or otherwise disposable instances. Keep long-running, incident-bearing, and audit-sensitive instances outside a deletion policy until you have verified the filter against representative data.

Install and enable the module

Add the extension to the server that owns the workflow management and runtime stores:

dotnet add package Elsa.Retention --version 3.8.0

Register it inside AddElsa. The retention module does not add a deletion policy by itself; no instances are selected until you call AddDeletePolicy or register a custom IRetentionPolicy.

using Elsa.Common;
using Elsa.Extensions;
using Elsa.Retention.Extensions;
using Elsa.Retention.Models;
using Elsa.Workflows;
using Microsoft.Extensions.DependencyInjection;

builder.Services.AddElsa(elsa =>
{
    // Configure UseWorkflowManagement and UseWorkflowRuntime with
    // the persistence providers used by this host.

    elsa.UseRetention(retention =>
    {
        retention.SweepInterval = TimeSpan.FromHours(4);
        retention.ConfigureCleanupOptions = options =>
        {
            options.PageSize = 25;
        };

        retention.AddDeletePolicy("Finished workflows", _ =>
            new RetentionWorkflowInstanceFilter
            {
                WorkflowStatus = WorkflowStatus.Finished
            });
    });
});

In 3.8.0, SweepInterval defaults to four hours and CleanupOptions.PageSize defaults to 25. PageSize is the number of workflow instances loaded into a cleanup batch; it is not a limit on the total number of instances a policy can delete. The filter factory is called on each cleanup run, so resolve services or calculate a moving time threshold inside the factory.

For the released registration and defaults, see UseRetention and RetentionFeature.

Define a bounded deletion policy

AddDeletePolicy takes a name and a factory returning RetentionWorkflowInstanceFilter. The filter supports:

  • workflow definition ID or definition version ID, including collections of IDs;

  • correlation ID, including a collection of IDs;

  • one workflow status or a collection of statuses;

  • one workflow sub-status or a collection of sub-statuses;

  • SearchTerm matching instance name, definition IDs, version ID, instance ID, or correlation ID;

  • HasIncidents and IsSystem; and

  • timestamp filters on CreatedAt, UpdatedAt, or FinishedAt.

Combine a lifecycle status with an age condition so a newly finished instance is not removed immediately:

RetentionWorkflowInstanceFilter is converted to Core's WorkflowInstanceFilter before querying the configured IWorkflowInstanceStore. Timestamp columns are validated by Core; arbitrary property names are not accepted. A timestamp filter with a date-only value has the release's day-boundary semantics, so use a precise DateTimeOffset when you need an exact age threshold.

What the default cleanup removes

For each page of matching workflow instances, the built-in deletion policy first collects and deletes related records, then deletes the workflow instances. The 3.8.0 module registers these default pairs:

  • StoredBookmarkIBookmarkStore

  • ActivityExecutionRecordIActivityExecutionStore

  • WorkflowExecutionLogRecordIWorkflowExecutionLogStore

  • WorkflowInstanceIWorkflowInstanceStore

The related records are loaded in smaller chunks by their collectors. A provider must therefore support the corresponding FindMany and delete operations for the policy to complete cleanly. The cleanup job logs and continues past a query failure for that policy, but missing cleanup strategies or a failed workflow-instance deletion are configuration or implementation errors that must be investigated.

The recurring task is marked [SingleNodeTask]. Elsa's task executor acquires a distributed lock for such tasks, so a clustered host should configure a shared distributed lock provider. This prevents every node from performing the same retention sweep. The lock does not make deletion recoverable and does not replace backups or a database transaction strategy.

Extend retention safely

Use IRelatedEntityCollector<TEntity> when a custom entity belongs to a workflow instance and must be cleaned up with it. Register a collector and the matching IDeletionCleanupStrategy<TEntity>:

The interfaces are intentionally generic. The collector returns entities for the current batch; the deletion strategy receives those entities and performs the cleanup. Make the operation idempotent because retries or an interrupted process can cause the same logical cleanup to be attempted again.

To implement a non-deletion policy, define a marker strategy interface such as IArchiveCleanupStrategy<TEntity> : ICleanupStrategy<TEntity>, implement that interface for every entity the policy must handle, and set IRetentionPolicy.CleanupStrategy to the open generic marker type. The module uses that marker to resolve strategies for related entities and the workflow instance itself. An archive policy is not supplied by the release; you own its storage, failure handling, and verification.

Operational checklist

  • Start with a narrow definition ID and a generous age threshold.

  • Test the filter against a copy or read-only query before enabling deletion.

  • Exclude instances with incidents, active work, or audit obligations unless the business policy explicitly permits their removal.

  • Use a durable, shared persistence provider and distributed lock provider in a multi-node deployment.

  • Set PageSize to fit the database and related-record query load; larger batches reduce scheduling overhead but increase deletion work per sweep.

  • Monitor cleanup logs and the provider's delete counts. Retention does not archive data, undo a deletion, or guarantee recovery after a failed sweep.

Release references

Last updated