> For the complete documentation index, see [llms.txt](https://docs.elsaworkflows.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.elsaworkflows.io/guides/persistence.md).

# Persistence

Comprehensive guide to choosing, configuring, and tuning persistence providers for Elsa Workflows v3, covering EF Core, MongoDB, Dapper, and Elasticsearch, along with retention, migrations, and operat

## Executive Summary

Elsa Workflows uses persistence providers to store workflow definitions, workflow instances, bookmarks, and execution logs. Choosing the right persistence strategy is critical for performance, scalability, and operational requirements. This guide covers:

* **Provider selection** — When to choose EF Core, MongoDB, Dapper, or Elasticsearch
* **Configuration patterns** — Connection strings, migrations, and store registration
* **Indexing recommendations** — Essential indexes for common queries
* **Retention & cleanup** — Managing completed workflows and bookmark cleanup
* **Migrations & versioning** — Handling schema changes and rolling upgrades
* **Observability** — Measuring persistence latency and tracing

## Persistence Stores Overview

Elsa organizes persistence into logical stores, each responsible for a specific data type:

| Store                            | Purpose                                         | Typical Table/Collection      |
| -------------------------------- | ----------------------------------------------- | ----------------------------- |
| **Workflow Definition Store**    | Stores published and draft workflow definitions | `WorkflowDefinitions`         |
| **Workflow Instance Store**      | Stores workflow execution state and history     | `WorkflowInstances`           |
| **Bookmark Store**               | Stores suspension points for workflow resume    | `Bookmarks`                   |
| **Activity Execution Store**     | Stores activity execution records               | `ActivityExecutionRecords`    |
| **Workflow Execution Log Store** | Stores detailed execution logs                  | `WorkflowExecutionLogRecords` |
| **Workflow Inbox Store**         | Stores incoming messages for correlation        | `WorkflowInboxMessages`       |

**Code Reference:** `src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs` — Registers workflow definition and instance stores.

**Code Reference:** `src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs` — Registers runtime stores (bookmarks, inbox, execution logs).

## Persistence Providers

Elsa supports several persistence providers. The provider is selected per store, so a deployment can combine providers when a specific workload needs it.

### Entity Framework Core (EF Core)

**Best for:** General-purpose relational database persistence with migration support.

**Supported Databases:**

* SQL Server
* PostgreSQL
* SQLite
* MySQL/MariaDB

**Pros:**

* ✅ Built-in migration support for schema versioning
* ✅ Mature ecosystem with robust tooling
* ✅ Transactional consistency across stores
* ✅ Wide database support

**Cons:**

* ❌ May have higher overhead for extremely high-throughput scenarios
* ❌ Requires migration management for schema changes

**When to Choose:**

* Production deployments requiring schema versioning
* Teams familiar with EF Core and relational databases
* Scenarios requiring transactional consistency

**Documentation:**

* [SQL Server Guide](/guides/persistence/sql-server.md) - Comprehensive SQL Server setup and configuration
* [EF Core Migrations Guide](/guides/persistence/ef-migrations.md) - Working with migrations and custom entities
* [EF Core Setup Example](/guides/persistence/efcore-setup.md) - Basic configuration patterns

### MongoDB

**Best for:** Document-oriented persistence with flexible schemas.

**Pros:**

* ✅ Flexible schema evolution without migrations
* ✅ Native document storage suits workflow state
* ✅ Horizontal scaling via sharding
* ✅ Built-in replication for high availability

**Cons:**

* ❌ No built-in migration tooling (schema changes require application logic)
* ❌ Custom indexes beyond Elsa's defaults must be managed manually
* ❌ Different consistency model than relational databases

**When to Choose:**

* Teams already using MongoDB
* Scenarios requiring flexible schema evolution
* High-volume workloads with horizontal scaling needs

See [MongoDB Setup Example](/guides/persistence/mongodb-setup.md) for configuration details.

### Dapper

**Best for:** Relational persistence when the team wants fine-grained SQL control and a built-in Dapper connection provider.

**Pros:**

* ✅ Minimal ORM overhead
* ✅ Direct SQL control for optimization
* ✅ Lower memory footprint

**Cons:**

* ❌ Requires the Dapper migrations feature or external schema management
* ❌ Requires SQL expertise for customization
* ❌ Less abstraction than EF Core

**When to Choose:**

* Extreme performance requirements
* Teams with strong SQL expertise
* Scenarios requiring custom query optimization

The 3.8.1 extension provides built-in connection providers for SQLite, SQL Server, and PostgreSQL. MySQL is not a built-in Dapper provider. See the [Dapper persistence guide](/guides/persistence/dapper-setup.md) for provider selection, SQL dialect behavior, and the FluentMigrator runner configuration required for automatic schema migrations.

If the persistence requirement is specifically scheduled Quartz jobs, see [Quartz Scheduling](/guides/running-workflows/quartz-scheduling.md). Quartz's job store is separate from Elsa's workflow-definition and workflow-instance stores.

### Elasticsearch

**Best for:** Deployments that already operate Elasticsearch and want workflow-instance and execution-log stores backed by Elasticsearch.

**Important boundary:** The 3.8.1 extension does not replace every Elsa store. It wires `IWorkflowInstanceStore` and `IWorkflowExecutionLogStore`; configure workflow definitions, bookmarks, inbox messages, and other stores separately. The release store also has filter and timestamp-update limitations, so validate your operational queries before choosing it as the primary persistence path.

See [Elasticsearch Setup Example](/guides/persistence/elasticsearch-setup.md) for the registration, index, authentication, and deployment guidance.

## Configuration Patterns

### Basic Configuration

All persistence providers are configured through the `services.AddElsa(...)` method:

```csharp
using Elsa.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddElsa(elsa =>
{
    // Configure workflow management (definitions, instances)
    elsa.UseWorkflowManagement(management =>
    {
        management.UseEntityFrameworkCore(ef =>
        {
            ef.UsePostgreSql(builder.Configuration.GetConnectionString("PostgreSql"));
        });
    });
    
    // Configure workflow runtime (bookmarks, inbox, execution logs)
    elsa.UseWorkflowRuntime(runtime =>
    {
        runtime.UseEntityFrameworkCore(ef =>
        {
            ef.UsePostgreSql(builder.Configuration.GetConnectionString("PostgreSql"));
        });
    });
    
    // Enable API endpoints
    elsa.UseWorkflowsApi();
});

var app = builder.Build();
app.Run();
```

**Code Reference:** `src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs` — Core services wire-up.

### Connection Strings

**appsettings.json:**

```json
{
  "ConnectionStrings": {
    "PostgreSql": "Host=localhost;Database=elsa;Username=elsa;Password=YOUR_PASSWORD;Port=5432",
    "SqlServer": "Server=localhost;Database=Elsa;User Id=sa;Password=YOUR_PASSWORD;TrustServerCertificate=true",
    "MongoDb": "mongodb://localhost:27017/elsa"
  }
}
```

**Environment Variables:**

```bash
CONNECTIONSTRINGS__POSTGRESQL="Host=localhost;Database=elsa;..."
CONNECTIONSTRINGS__MONGODB="mongodb://localhost:27017/elsa"
```

### EF Core Migrations

For EF Core providers, migrations manage schema changes:

**1. Install EF Core Tools:**

```bash
dotnet tool install --global dotnet-ef
```

**2. Apply Migrations at Startup (Recommended for Development):**

```csharp
elsa.UseWorkflowManagement(management =>
{
    management.UseEntityFrameworkCore(ef =>
    {
        ef.UsePostgreSql(connectionString);
        ef.RunMigrations = true;  // Apply migrations on startup
    });
});
```

**3. Apply Migrations via CLI (Recommended for Production):**

```bash
# Generate migrations
dotnet ef migrations add InitialCreate --context ManagementElsaDbContext

# Apply migrations
dotnet ef database update --context ManagementElsaDbContext
```

**Schema Versioning Notes:**

* Always test migrations in a non-production environment first
* Use a staging database identical to production for migration testing
* Consider blue-green deployments for zero-downtime migrations
* Keep migration scripts in source control

For detailed information on working with EF Core migrations, adding custom entities, and migration strategies, see the [EF Core Migrations Guide](/guides/persistence/ef-migrations.md).

### MongoDB Configuration

MongoDB does not use migrations. Configure the shared MongoDB connection at the Elsa module level, then select MongoDB for the management and runtime stores:

```csharp
var connectionString = builder.Configuration.GetConnectionString("MongoDb")!;

builder.Services.AddElsa(elsa =>
{
    elsa.UseMongoDb(connectionString);

    elsa.UseWorkflowManagement(management =>
    {
        management.UseMongoDb();
    });

    elsa.UseWorkflowRuntime(runtime =>
    {
        runtime.UseMongoDb();
    });
});
```

The database name comes from the MongoDB connection string. Elsa creates its MongoDB indexes on startup and uses snake\_case collection names such as `workflow_definitions`, `workflow_instances`, `bookmarks`, `workflow_execution_logs`, and `activity_execution_logs`.

**Custom Indexes:** Create any additional workload-specific indexes yourself. See [Indexing Notes](/guides/persistence/indexing-notes.md) for examples and refer to [MongoDB Index Documentation](https://www.mongodb.com/docs/manual/indexes/) for detailed guidance.

**Mapping Considerations:**

* Elsa uses MongoDB driver's conventions for BSON serialization
* Custom activity data must be serializable to BSON
* Consider using `BsonIgnore` attribute for non-persisted properties

### Dapper Configuration

Dapper requires module-level connection-provider configuration, followed by explicit Dapper registration for workflow management and runtime. The provider also selects the SQL dialect used by the stores. See the [Dapper persistence guide](/guides/persistence/dapper-setup.md) for complete SQLite and SQL Server examples, PostgreSQL boundaries, and custom-provider guidance.

**Schema Responsibility:**

* Use a configured `dapper.UseMigrations(...)` runner to run Elsa's Dapper migrations for supported databases
* If you do not enable Elsa migrations, you are responsible for creating and maintaining the database schema
* Elsa's Dapper migrations create PascalCase tables and columns such as `WorkflowInstances`, `Bookmarks`, and `WorkflowExecutionLogRecords`
* See [Dapper Setup Example](/guides/persistence/dapper-setup.md) for a complete setup

## Interrupted-workflow recovery in 3.8.1

Force-drain recovery depends on the workflow-instance store, not only on the runtime store. When Elsa interrupts an active execution, it conditionally updates the instance to `Status = Running`, `SubStatus = Interrupted`, and `IsExecuting = false`. The conditional write refuses to overwrite a finished or faulted instance; a cancelled finished instance is eligible only when the runtime has evidence that the drain caused the cancellation. On the next activation, the runtime scans persisted `Running` + `Interrupted` instances and requeues them.

The 3.8.1 release implements this contract as follows:

| Provider      | Conditional interruption write       | Restart recovery after process exit                                                                                  | Operational boundary                                                     |
| ------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| EF Core       | Yes (`TryMarkInterruptedAsync`)      | Yes, when the management, runtime, bookmark, and execution-log stores are durable                                    | Use a shared database and distributed locking for multiple nodes         |
| Dapper        | Yes                                  | Yes, with the Dapper workflow-instance schema and durable runtime stores                                             | Apply the Dapper schema before enabling recovery                         |
| MongoDB       | Yes                                  | Yes, with durable MongoDB collections and runtime stores                                                             | Use a durable deployment; replica-set behavior remains a MongoDB concern |
| Elasticsearch | Yes                                  | Yes, with its workflow-instance and execution-log stores durable plus companion runtime stores configured separately | Validate update-by-query permissions and refresh behavior in the cluster |
| In-memory     | Yes, only in the process-local store | No; process exit removes the records needed by startup recovery                                                      | Suitable for development or explicitly disposable runs only              |

Custom workflow-instance stores must implement `IWorkflowInstanceStore.TryMarkInterruptedAsync` with the same conditional semantics to participate safely in force-drain recovery. A store that only loads an instance, mutates a snapshot, and saves it can race a terminal completion and reintroduce an already-finished workflow as interrupted.

The release implementations are visible in Core's [`IWorkflowInstanceStore`](https://github.com/elsa-workflows/elsa-core/blob/release/3.8.1/src/modules/Elsa.Workflows.Management/Contracts/IWorkflowInstanceStore.cs) and [`MemoryWorkflowInstanceStore`](https://github.com/elsa-workflows/elsa-core/blob/release/3.8.1/src/modules/Elsa.Workflows.Management/Stores/MemoryWorkflowInstanceStore.cs), the EF Core [`WorkflowInstanceStore`](https://github.com/elsa-workflows/elsa-core/blob/release/3.8.1/src/modules/Elsa.Persistence.EFCore/Modules/Management/WorkflowInstanceStore.cs), and the Extensions implementations for [Dapper](https://github.com/elsa-workflows/elsa-extensions/blob/release/3.8.1/src/modules/persistence/Elsa.Persistence.Dapper/Modules/Management/Stores/DapperWorkflowInstanceStore.cs), [MongoDB](https://github.com/elsa-workflows/elsa-extensions/blob/release/3.8.1/src/modules/persistence/Elsa.Persistence.MongoDb/Modules/Management/WorkflowInstanceStore.cs), and [Elasticsearch](https://github.com/elsa-workflows/elsa-extensions/blob/release/3.8.1/src/modules/persistence/Elsa.Persistence.Elasticsearch/Modules/Management/WorkflowInstanceStore.cs).

### Verify a provider before relying on recovery

Run this checklist for every deployment that uses force-drain or expects interrupted workflows to survive a restart:

1. Confirm that `IWorkflowInstanceStore` is backed by the provider you intend to use; do not assume that configuring a runtime store also configures the workflow-instance store.
2. Confirm that the provider implements the conditional interruption update and that it does not update `Finished` or `Faulted` instances.
3. Confirm durable storage for workflow instances, bookmarks, and execution logs. Startup recovery cannot reconstruct a workflow from an in-memory store after the process exits.
4. In a non-production environment, force-drain a deliberately long-running instance, verify its `Running` + `Interrupted` state and `WorkflowInterrupted` log entry, restart the host, and verify that it is requeued once.
5. For a multi-node deployment, verify shared persistence, distributed locking, tenant context, and the provider's update/transaction behavior under concurrent completion.

The runtime operation, interruption reasons, and startup scan are documented in [Runtime administration and graceful drain](/operate/runtime-administration.md).

## Indexes & Queries

Proper indexing is essential for production performance. Create indexes for frequently queried columns:

### Recommended Indexes

**Workflow Instances:**

```sql
-- Query by instance ID (primary key in most providers)
-- Query by correlation ID
CREATE INDEX idx_workflow_instances_correlation_id ON "WorkflowInstances"("CorrelationId");

-- Query by status (running, suspended, completed, faulted)
CREATE INDEX idx_workflow_instances_status ON "WorkflowInstances"("Status");

-- Query by definition ID
CREATE INDEX idx_workflow_instances_definition_id ON "WorkflowInstances"("DefinitionId");

-- Query by updated timestamp (for retention/cleanup)
CREATE INDEX idx_workflow_instances_updated_at ON "WorkflowInstances"("UpdatedAt");

-- Composite index for common queries
CREATE INDEX idx_workflow_instances_status_definition ON "WorkflowInstances"("Status", "DefinitionId");
```

**Bookmarks:**

```sql
-- Query by activity type + stimulus hash (primary lookup path)
CREATE INDEX idx_bookmarks_activity_type_hash ON "Bookmarks"("ActivityTypeName", "Hash");

-- Query by workflow instance ID (for cleanup)
CREATE INDEX idx_bookmarks_workflow_instance_id ON "Bookmarks"("WorkflowInstanceId");

-- Query by correlation ID
CREATE INDEX idx_bookmarks_correlation_id ON "Bookmarks"("CorrelationId");
```

**Incidents:**

```sql
-- Query by workflow instance ID
CREATE INDEX idx_incidents_workflow_instance_id ON "Incidents"("WorkflowInstanceId");

-- Query by timestamp (for monitoring dashboards)
CREATE INDEX idx_incidents_timestamp ON "Incidents"("Timestamp");
```

**Code Reference:** `src/modules/Elsa.Workflows.Core/Bookmarks/*` — Bookmark hashing and storage logic.

See [Indexing Notes](/guides/persistence/indexing-notes.md) for provider-specific guidance.

> **Note:** Defer detailed vendor-specific index tuning (covering indexes, partial indexes, index-only scans) to official database documentation.

## Retention & Cleanup

Over time, completed workflow instances and their runtime records accumulate. Elsa 3.8.1 provides retention through the separate `Elsa.Retention` extension. It selects instances with `RetentionWorkflowInstanceFilter` and, for the built-in deletion policy, removes the related bookmarks, activity execution records, workflow execution logs, and workflow instances.

See [Retention](/optimize/retention.md) for the package registration, age-filter example, page-size and sweep settings, clustered-host locking, custom cleanup strategies, and the destructive-operation checklist. Configure retention alongside the management and runtime persistence stores it will clean; it does not replace backups or archive data.

### Bookmark Cleanup

Orphaned bookmarks (where the associated workflow instance no longer exists) should be cleaned up:

```sql
-- Find orphaned bookmarks
SELECT b.* FROM "Bookmarks" b
LEFT JOIN "WorkflowInstances" wi ON b."WorkflowInstanceId" = wi."Id"
WHERE wi."Id" IS NULL;

-- Delete orphaned bookmarks
DELETE FROM "Bookmarks"
WHERE "WorkflowInstanceId" NOT IN (SELECT "Id" FROM "WorkflowInstances");
```

### Workflow Inbox Cleanup

The `WorkflowInboxCleanup` job removes stale inbox messages:

```csharp
elsa.UseWorkflowRuntime(runtime =>
{
    runtime.WorkflowInboxCleanupOptions = options =>
    {
        options.SweepInterval = TimeSpan.FromHours(1);
        options.Ttl = TimeSpan.FromDays(7);  // Remove messages older than 7 days
    };
});
```

**Code Reference:** `src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs` — Inbox cleanup options.

### Manual Cleanup (SQL)

For immediate cleanup needs:

```sql
-- Delete completed workflows older than 30 days
DELETE FROM "WorkflowInstances"
WHERE "Status" = 'Finished'
  AND "FinishedAt" < NOW() - INTERVAL '30 days';

-- Delete activity execution records for deleted instances
DELETE FROM "ActivityExecutionRecords"
WHERE "WorkflowInstanceId" NOT IN (SELECT "Id" FROM "WorkflowInstances");

-- Delete execution logs for deleted instances
DELETE FROM "WorkflowExecutionLogRecords"
WHERE "WorkflowInstanceId" NOT IN (SELECT "Id" FROM "WorkflowInstances");
```

## Backup & Restore

### Environment Consistency

When backing up and restoring Elsa databases:

1. **Version Alignment:** Ensure the Elsa version in your application matches the schema version in the database. Mismatched versions can cause runtime errors.
2. **Consistent Backups:** For clustered deployments, quiesce the cluster or use database-native snapshot capabilities to ensure consistency.
3. **Include All Stores:** If using separate databases for management and runtime stores, back up both.
4. **Test Restores:** Regularly test restore procedures in a non-production environment.

### Backup Commands

**PostgreSQL:**

```bash
# Full backup
pg_dump -h localhost -U elsa -d elsa -F c -f elsa_backup.dump

# Restore
pg_restore -h localhost -U elsa -d elsa elsa_backup.dump
```

**SQL Server:**

```sql
BACKUP DATABASE [Elsa] TO DISK = 'C:\Backups\Elsa.bak';

RESTORE DATABASE [Elsa] FROM DISK = 'C:\Backups\Elsa.bak';
```

**MongoDB:**

```bash
# Backup
mongodump --uri="mongodb://localhost:27017/elsa" --out=/backup/elsa

# Restore
mongorestore --uri="mongodb://localhost:27017/elsa" /backup/elsa
```

## Migrations & Versioning

### Managing Breaking Changes

When Elsa releases a new version with schema changes:

1. **Review Release Notes:** Check for migration steps or breaking changes.
2. **Test in Staging:** Apply migrations to a staging environment first.
3. **Rolling Upgrades:** For clustered deployments:
   * Apply database migrations first (backward-compatible changes)
   * Roll out new application version to nodes one at a time
   * Monitor for errors during transition
4. **Rollback Plan:** Keep database backups and have a rollback strategy.

### EF Core Migration Steps

**1. Update Elsa Packages:**

```bash
dotnet add package Elsa --version 3.x.x
dotnet add package Elsa.Persistence.EFCore.PostgreSql --version 3.x.x
```

**2. Generate Migration:**

```bash
dotnet ef migrations add UpdateToVersion3xx --context ManagementElsaDbContext
```

**3. Review Migration:** Inspect the generated migration file for potentially destructive changes.

**4. Apply Migration:**

```bash
# Development
dotnet ef database update --context ManagementElsaDbContext

# Production (generate SQL script for review)
dotnet ef migrations script --context ManagementElsaDbContext --idempotent
```

### Schema Versioning Best Practices

* Keep migrations in source control alongside application code
* Use semantic versioning to correlate Elsa versions with schema versions
* Document any manual data transformations required between versions
* Consider database branching strategies for team development

## Observability & Performance

### Measuring Persistence Latency

Monitor database operations to identify bottlenecks:

```csharp
using OpenTelemetry.Trace;

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing =>
    {
        tracing
            .AddAspNetCoreInstrumentation()
            .AddNpgsql()  // PostgreSQL instrumentation
            .AddSource("Elsa.Workflows")
            .AddOtlpExporter();
    });
```

### Key Metrics to Monitor

| Metric                                 | Description                     | Alert Threshold   |
| -------------------------------------- | ------------------------------- | ----------------- |
| `db.query.duration`                    | Database query execution time   | P95 > 500ms       |
| `elsa.workflow_instance.save.duration` | Workflow state persistence time | P95 > 1000ms      |
| `elsa.bookmark.lookup.duration`        | Bookmark query time             | P95 > 100ms       |
| `db.connection.pool.active`            | Active database connections     | > 80% of max pool |

### Tracing and telemetry

For distributed tracing of workflow execution alongside persistence telemetry, use the optional `Elsa.OpenTelemetry` extension and register its workflow and activity pipeline middleware. See [OpenTelemetry workflow and activity tracing](/extensibility/opentelemetry-tracing.md) for the release-backed setup and span fields.

See [Performance & Scaling Guide](/guides/performance.md) and [Monitoring & Observability](/operate/monitoring-observability.md) for the release-backed observability setup.

> **Note:** Core `WorkflowInstrumentation` emits baseline workflow/activity spans and a workflow meter. The `Elsa.OpenTelemetry` extension adds another span layer through the same activity source; it does not add another meter.

## Common Pitfalls

### 1. Long Transactions

**Problem:** Workflows with many activities in a single burst can hold database locks for extended periods.

**Symptoms:**

* Lock wait timeouts
* Blocked queries
* Degraded throughput under load

**Mitigation:**

* Use commit strategies to limit transaction scope (see [Performance Guide](/guides/performance.md))
* Configure shorter lock timeouts
* Consider breaking large workflows into smaller sub-workflows

### 2. High-Cardinality Bookmarks

**Problem:** Workflows creating many unique bookmarks (e.g., one per user or order) can overwhelm the bookmark index.

**Symptoms:**

* Slow bookmark lookups
* Index bloat
* Memory pressure

**Mitigation:**

* Limit bookmark cardinality by design
* Use correlation IDs to group related bookmarks
* Implement bookmark cleanup policies

**Code Reference:** `src/modules/Elsa.Workflows.Core/Bookmarks/*` — Understand bookmark hashing to design efficient bookmark strategies.

### 3. Missing Indexes

**Problem:** Production deployments without proper indexes suffer degraded query performance.

**Symptoms:**

* Full table scans in query plans
* Slow workflow list/search operations
* High database CPU

**Mitigation:**

* Apply recommended indexes (see [Indexing Notes](/guides/persistence/indexing-notes.md))
* Monitor slow query logs
* Use database-native query analysis tools

### 4. Noisy Logging of Large Payloads

**Problem:** Logging workflow inputs/outputs can expose sensitive data and bloat logs.

**Symptoms:**

* Excessive log volume
* Sensitive data in logs
* Log aggregation costs

**Mitigation:**

* Configure log levels appropriately for production
* Use structured logging with field exclusions
* Consider log retention policies

```json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Elsa": "Warning",
      "Elsa.Workflows.Runtime": "Information"
    }
  }
}
```

### 5. Connection Pool Exhaustion

**Problem:** High-concurrency workflows exhaust database connection pools.

**Symptoms:**

* Timeout waiting for connection
* Intermittent failures under load
* Degraded throughput

**Mitigation:**

* Increase connection pool size appropriately
* Monitor pool utilization metrics
* Configure connection timeout and retry policies

```csharp
// PostgreSQL example with pool settings
var connectionString = "Host=localhost;Database=elsa;Username=elsa;Password=...;MaxPoolSize=100;MinPoolSize=10";
```

## Related Documentation

* [SQL Server Guide](/guides/persistence/sql-server.md) — Complete SQL Server configuration and troubleshooting
* [EF Core Migrations Guide](/guides/persistence/ef-migrations.md) — Working with migrations and custom entities
* [Clustering Guide](/guides/clustering.md) — Distributed deployment and distributed locking (DOC-015)
* [Troubleshooting Guide](/guides/troubleshooting.md) — Diagnosing common issues (DOC-017)
* [Performance & Scaling Guide](/guides/performance.md) — Commit strategies and observability (DOC-021)
* [Database Configuration](/getting-started/database-configuration.md) — Basic database setup
* [Retention](/optimize/retention.md) — Detailed retention configuration
* [Log Persistence](/optimize/log-persistence.md) — Activity log optimization

## Example Files

* [EF Core Setup Example](/guides/persistence/efcore-setup.md)
* [MongoDB Setup Example](/guides/persistence/mongodb-setup.md)
* [Dapper Setup Example](/guides/persistence/dapper-setup.md)
* [Indexing Notes](/guides/persistence/indexing-notes.md)
* [Source File References](https://github.com/elsa-workflows/elsa-gitbook/tree/main/guides/persistence/README-REFERENCES.md)

***

**Last Updated:** 2025-11-28
