# Workflow Engine Database Providers for .NET Source: https://workflowengine.io/features/multi-database/ Site index for agents: https://workflowengine.io/llms.txt (products, licensing, documentation hosts, package names). **Workflow Engine keeps its state in the database you already run** v22.1.0 · six providers, nine databases · one NuGet package and one connection string · included in every product · Page last updated 1 October 2026 Workflow Engine by Optimajet is a .NET library, so it has no datastore of its own and asks you to deploy nothing. Install the provider for your database, pass a connection string, and the engine creates its tables there. Process state, timers, schemes, and history end up next to your business data, inside the backup policy, the failover plan, and the access rules your team already runs. Persistence layer · one interface, six providers · IPersistenceProvider One provider is active in a running application, and the orange outline marks it the way the designer marks a selected element. Swapping the highlighted lane means a different NuGet package and a different connection string. The code above the interface does not change. ## Six providers sit behind one interface, so you can · swap the database and keep the workflow code Every process instance, timer, scheme, and history record that [Workflow Engine](https://workflowengine.io/products/dotnet-workflow-engine/) produces has to survive a restart, so the runtime always writes to a database. The question a .NET team actually faces is not whether to use one. It is whose database, and who ends up operating it. The answer here is yours. A persistence provider translates the runtime's calls into native SQL, or document operations for MongoDB, against a database your organization already manages. Nothing in the engine holds state outside that database, which is why several instances can share one and why a restart loses nothing. ### Six providers, nine databases SQL Server, PostgreSQL, MySQL, MongoDB, Oracle, and SQLite. The SQL Server provider also serves Azure SQL and Azure SQL Managed Instance; the MongoDB provider also serves Azure Cosmos DB. Initial activity ### One interface behind all of them Every provider implements IPersistenceProvider. Your application code calls WorkflowRuntime, never the database, so the provider is the only thing that knows which engine is underneath. ### One NuGet package per database Install WorkflowEngine.NETCore-ProviderFor{Name} for your database and nothing else. The provider pulls in the migrator it needs on its own. ### Tables in your database RunMigrations() creates the workflow tables and three stored procedures in the database your connection string points at. Your backups, your replication, your retention rules, your access control. ### The database is the cluster In multi-server mode, instances coordinate through the shared database with row locks and alive signals. No message broker, no coordination service, no separate cluster to operate. ### Free in every product The providers are part of the core runtime, not an add-on. Workflow Engine Free reads and writes the same schema as a licensed production deployment. Current activity ## Six providers cover nine databases Each provider is its own NuGet package, so you install exactly one and carry no driver you do not use. Two of them cover more than one product. The SQL Server provider serves Azure SQL and Azure SQL Managed Instance as well, and the MongoDB provider serves Azure Cosmos DB, which is how six packages reach nine databases. Runtime floors differ, and the table says so rather than making you find out at restore time. | Database | NuGet package | Version | Runs on | | --- | --- | --- | --- | | SQL Server, Azure SQL | [WorkflowEngine.NETCore-ProviderForMSSQL](https://www.nuget.org/packages/WorkflowEngine.NETCore-ProviderForMSSQL/) | v22.1.0 | .NET Framework 4.6.2+ and all modern .NET | | PostgreSQL | [WorkflowEngine.NETCore-ProviderForPostgreSQL](https://www.nuget.org/packages/WorkflowEngine.NETCore-ProviderForPostgreSQL/) | v22.1.0 | .NET Framework 4.6.2+ and all modern .NET | | MySQL | [WorkflowEngine.NETCore-ProviderForMySQL](https://www.nuget.org/packages/WorkflowEngine.NETCore-ProviderForMySQL/) | v22.1.0 | .NET Framework 4.6.2+ and all modern .NET | | MongoDB, Azure Cosmos DB | [WorkflowEngine.NETCore-ProviderForMongoDB](https://www.nuget.org/packages/WorkflowEngine.NETCore-ProviderForMongoDB/) | v22.1.0 | .NET Framework 4.6.2+ and all modern .NET | | Oracle | [WorkflowEngine.NETCore-ProviderForOracle](https://www.nuget.org/packages/WorkflowEngine.NETCore-ProviderForOracle/) | v22.1.0 | .NET Core 3.0 and later | | SQLite | [WorkflowEngine.NETCore-ProviderForSQLite](https://www.nuget.org/packages/WorkflowEngine.NETCore-ProviderForSQLite/) | v22.1.0 | .NET 8 and laterFor evaluation. Not recommended for production use. | ### On classic .NET Framework The SQL Server, PostgreSQL, MySQL, and MongoDB providers target netstandard2.0 and run on .NET Framework 4.6.2 and later, which matters for the applications most likely to be replacing Windows Workflow Foundation. ### On modern .NET All six providers run on current .NET. Oracle and SQLite are the two to check before a legacy port, because neither runs on classic .NET Framework. The table above carries the floor for each one. ### In Workflow Engine NEO The Workflow Engine HTTP API registers the same providers through one dependency injection helper per database, such as AddWorkflowApiPostgres or AddWorkflowApiMssql, so the hosted API and the embedded library make the same storage choice. Package versions, the .NET Framework and .NET Core install paths, and the sample projects are on the [Workflow Engine downloads page](https://workflowengine.io/downloads/). ## A connection string and one line of startup code There is no schema to design, no ORM to configure, and no SQL script to find for your version. You construct the provider for your database, hand it to the runtime, and call RunMigrations() before starting. On first run the tables appear. On every run after that the call finds nothing to do and returns. Install the provider for your database · bash ```bash dotnet add package WorkflowEngine.NETCore-Core dotnet add package WorkflowEngine.NETCore-ProviderForPostgreSQL ``` Point the runtime at it · csharp ```csharp var runtime = new WorkflowRuntime() .WithPersistenceProvider(new PostgreSQLProvider(connectionString)) .RunMigrations() .AsSingleServer(); await runtime.StartAsync(); ``` Every provider is constructed the same way, so moving a proof of concept from SQLite to the database your team runs in production is a package reference and a type name. The same call, one provider per database · csharp ```csharp new MSSQLProvider(connectionString) // SQL Server, Azure SQL, Managed Instance new PostgreSQLProvider(connectionString) // PostgreSQL new MySQLProvider(connectionString) // MySQL new MongoDBProvider(connectionString) // MongoDB, Azure Cosmos DB new OracleProvider(connectionString) // Oracle new SQLiteProvider(connectionString) // SQLite, evaluation only ``` The provider package pulls in [`WorkflowEngine.NETCore-Migrator`](https://www.nuget.org/packages/WorkflowEngine.NETCore-Migrator/) on its own, so schema setup needs no extra reference. Full startup sequences, including the dependency injection variant, are in the [Workflow Engine installation guide](https://docs.workflowengine.io/get-started/install-workflow-engine/). ## Workflow state you can read with SELECT Nothing about the workflow state is opaque. The schema is the short list of tables below plus three stored procedures, created in your default schema, dbo on SQL Server, with GUID keys and ordinary columns. A support engineer can answer "where is invoice 4417 stuck" with a join, an auditor can read the transition history without an export, and your existing monitoring can alert on a timer queue that stops draining. The Every Workflow Engine license stores TenantId on the process record. Your application uses that value to build its [tenant model](https://workflowengine.io/features/multi-tenancy/). NEO adds ready multitenancy across the built-in Workflow Engine HTTP API operations. | Table | What it holds | | --- | --- | | WorkflowProcessInstance | One row per process: current activity and state, scheme id, parent and root process, TenantId, creation and last transition dates. | | WorkflowProcessInstanceStatus | Status and the lock that keeps two servers from running the same process at once. Status codes run 0 Initialized to 5 Error. | | WorkflowProcessInstancePersistence | Process parameters as key and value rows, one row per parameter. | | WorkflowProcessTransitionHistory | The execution log: every transition, who triggered it, when, and whether it finished. | | WorkflowProcessScheme | The scheme each running process is pinned to, so a scheme change does not rewrite processes already in flight. | | WorkflowScheme | The catalog of scheme definitions the designer reads and writes. | | WorkflowProcessTimer | Pending timers with their fire times. This is the table the timer poller reads. | | WorkflowGlobalParameter | Global parameters and global Code Actions shared across processes. | | WorkflowApprovalHistory | Approval Plugin history, recording who approved or rejected what, and in which order. | | WorkflowInbox | Approval Plugin inbox cache, the per-user task list the plugin reads from. | | WorkflowProcessAssignment | Assignment Plugin storage. The plugin is obsolete from v21, and the table stays for existing data. | | WorkflowRuntime | The multi-server registry, one row per runtime instance with its lock, status, next timer time, and last alive signal. | | WorkflowSync | The distributed lock table. Named locks keep cluster-wide operations from overlapping. | The three stored procedures are housekeeping. DropUnusedWorkflowProcessScheme deletes obsolete schemes that no instance still references, DropWorkflowInbox clears one process out of the inbox cache, and spWorkflowProcessResetRunningStatus is the manual recovery for stuck processes, moving them from Running back to Idled. ## Schema upgrades your DBA can still review Automatic schema management has been in the runtime since version 13.0.0, and it runs on FluentMigrator underneath. Teams that let applications create their own tables get a one-line upgrade. Teams whose change-control process forbids that get the same migrations as reviewable SQL, because every provider package ships its scripts as embedded, ordered files. Both paths end at the same schema. 01 ### The runtime knows its own schema Each provider ships the migration steps its database needs, written in the SQL dialect of that database. RunMigrations() applies the ones the current runtime version requires. 02 ### FluentMigrator tracks what ran Applied steps are recorded in a VersionInfo table. On start the runtime compares that record with the version it needs and applies only the gap. 03 ### Calling it again costs nothing The method is idempotent. On an up-to-date database it returns immediately, which is why it is safe to leave in the startup path of every environment. 04 ### Upgrades are a package bump Moving to a new Workflow Engine version updates the NuGet reference; the pending migrations run on the next start. Version 22.0.0 ships mandatory database migrations, so this path is the supported one. Where the call belongs in the startup chain · csharp ```csharp var runtime = new WorkflowRuntime() .WithPersistenceProvider(new MSSQLProvider(connectionString)) .RunMigrations(); // after the provider, before StartAsync() await runtime.StartAsync(); ``` Two caveats worth knowing before you plan an upgrade window. RunMigrations() covers SQL Server, PostgreSQL, MySQL, Oracle, and SQLite; MongoDB manages its schema differently, and its collections and indexes are created by the provider at runtime. And if you add migrations of your own to the same database, start their order numbers at 2 000 000 so they never collide with the built-in ones. The reference is in the [database versioning documentation](https://docs.workflowengine.io/evaluate/workflow-engine-features/database-versioning/). ## The database is the coordination layer This is where choosing your own database stops being a convenience and starts paying for itself. Scaling Workflow Engine across servers adds no infrastructure. Call AsMultiServer() on each instance, point them at the same database, and they coordinate through it. There is no broker to size, no consensus service to patch, and no vendor cluster in the path between your application and its data. ### Timers Every instance polls for due timers on its own interval, 1000 ms by default, and takes a database lock before executing one. A timer fires once across the cluster. ### Liveness Each instance writes an alive signal into the WorkflowRuntime table. Miss enough of them, the default is 60 intervals, and the instance is marked Terminated by the others. ### Recovery A surviving instance takes over the work of the one that stopped signalling. One healthy instance is enough for the cluster to keep running. ### Membership All instances are equal and there is no master. They never talk to each other directly; the shared database is the only thing they have in common. Same code on every node, one unique id each · csharp ```csharp var runtime = new WorkflowRuntime("node-01") .WithPersistenceProvider(new PostgreSQLProvider(connectionString)) .RunMigrations() .AsMultiServer(); ``` Two honest notes. Every instance sharing a database must run the same settings, and no load balancer is included, so incoming HTTP traffic is still yours to distribute. Multi-server mode is part of the commercial licensing and Workflow Engine Free runs single-server; the editions are listed on the [Workflow Engine pricing page](https://workflowengine.io/pricing/). ## What to settle before the first production deploy Four constraints decide how this feature lands in a real deployment. They are cheap to design around on day one and expensive to discover later, so they are on this page rather than in a support thread. ### Choose the database before production Switching providers once process instances exist is not supported, and no cross-provider migration tool ships. Each provider stores runtime data in its own native format. Different WorkflowRuntime instances may use different providers, so SQLite in development beside PostgreSQL in production is fine, but one live database does not move to another engine. ### SQLite is for evaluation The SQLite provider exists for local development and single-machine scenarios. It is not recommended for industrial use, it does not run on classic .NET Framework, and this version of SQLite may not work on macOS with Apple Silicon processors. ### The engine is not transactional Workflow Engine is thread-safe but not transactional, and there is no transaction spanning several commands. If a domain write must be atomic with a workflow transition, that atomicity belongs in your code and your database, the same way you handle it elsewhere. ### MongoDB is the different one The MongoDB provider carries the same schema contract in a document model, but RunMigrations() does not apply to it. Five of the six providers implement IMigratable; MongoDB creates collections and indexes at runtime instead. - A database is required. Workflow Engine does not run with in-memory state only. - The same six providers back every product in the lineup, so the storage decision survives a move from the library to Workflow Engine NEO. - A database outside the six is supported through the public IPersistenceProvider interface, with the maintenance of that provider on you. How the products differ elsewhere, from licensing to the hosted HTTP API, is laid out on the [product comparison page](https://workflowengine.io/products/compare/). ## Common questions The questions that come up in an infrastructure review: which databases, who creates the tables, what happens on an upgrade, and what the engine cannot do. 1. ### Which databases does Workflow Engine support? Six persistence provider packages cover nine database and deployment targets: Microsoft SQL Server, Azure SQL Database, Azure SQL Managed Instance, PostgreSQL, MySQL, Oracle, MongoDB, Azure Cosmos DB through its MongoDB-compatible API, and SQLite. Each provider is a separate NuGet package named WorkflowEngine.NETCore-ProviderFor{Name}, and each implements IPersistenceProvider. 2. ### Does Workflow Engine need its own database server? No. Workflow Engine uses a database that you configure through a persistence provider, and it can be one you already operate. For SQL Server, PostgreSQL, MySQL, Oracle, and SQLite, call RunMigrations() to create or update the provider-specific schema. MongoDB does not use RunMigrations(); follow the release notes for required update and index scripts. No separate Optimajet storage service or message broker is required. 3. ### Does the provider create the database tables automatically? Not merely by installing a provider package. For SQL Server, PostgreSQL, MySQL, Oracle, and SQLite, an explicit RunMigrations() call creates or updates the provider-specific schema. If the schema is current, no migration scripts are executed. MongoDB does not support RunMigrations(); apply version-specific update and index scripts when the release notes require them. 4. ### Can I switch databases after processes are running? No. Switching the persistence provider once process instances exist is not supported, and there is no cross-provider migration tool. Each provider stores runtime data in its native format. Pick the database before the first production deployment. Different WorkflowRuntime instances can use different providers, so a development instance on SQLite alongside a production instance on PostgreSQL is fine. 5. ### Is multi-database support a paid feature? No. The six built-in persistence providers are available in Workflow Engine Free and every edition of Workflow Engine and Workflow Engine NEO. Workflow Engine Free remains limited to personal use and internal commercial use, with attribution. Multi-server deployment is separate: it is available with Workflow Engine Complete and every edition of Workflow Engine NEO; Workflow Engine Free and Workflow Engine Team are single-server. 6. ### Can I use a database that is not on the list? Yes, but IPersistenceProvider covers runtime persistence rather than the whole built-in provider contract. A complete integration must also supply scheme persistence and generation to a configured WorkflowBuilder, either through IWorkflowProvider or through the separate scheme contracts, and register both with WorkflowRuntime. You own the custom provider and its compatibility with future releases. 7. ### Do I need a message broker or a separate cluster to run on several servers? No separate message broker or Workflow Engine coordination cluster is required. Each application node runs a Workflow Runtime instance against a shared database; process locks, timer claims, and heartbeat records coordinate the nodes. SQL Server, PostgreSQL, MySQL, MongoDB, and Oracle are documented for multi-server deployment; SQLite is for local or single-node use. A surviving node can recover eligible persisted process state under the configured recovery policy, but it does not resume the exact interrupted instruction or restore temporary in-memory state. The database must meet its own deployment requirements, including MongoDB cluster requirements, and incoming HTTP traffic needs your load balancer. 8. ### Can I query workflow data with my normal SQL tools? Yes, for SQL Server, PostgreSQL, MySQL, Oracle, and SQLite. Persisted workflow data uses provider-specific tables that you can inspect with native query tools; physical names, functions, and procedures differ, and the three stored procedures described elsewhere are specific to SQL Server. Transition history is queryable when its persistence is enabled. MongoDB uses collections and document queries. Backup, replication, retention, and access-control policies cover workflow data only when configured to include the target database and schema or collections. 9. ### Is SQLite suitable for production? SQLite is supported. It is useful for evaluation and local or single-machine development, but it is not recommended for production workloads; validate concurrency and durability requirements for your deployment. The current SQLite provider targets .NET 8 and .NET 10 and does not run on classic .NET Framework. 10. ### Can one transaction span several workflow commands and domain writes? No. Individual provider operations can use local database transactions, but Workflow Engine does not provide one engine-level transaction across several workflow commands or automatically include your domain writes. Coordinate that atomicity in your application and database. ## Point it at a database and see what it creates The fastest way to check any of this is an empty schema. Install Workflow Engine Free and the provider for your database, call RunMigrations(), and look at what appears. It is the same schema a licensed production deployment uses. Still comparing options? The [Multi-Database Support documentation](https://docs.workflowengine.io/evaluate/workflow-engine-features/multi-database-support/) covers the provider interface and the per-database install steps before you commit to anything. ## Sitemap [Sitemap of workflowengine.io](https://workflowengine.io/sitemap.md): every page of the site, with the description each page carries.