Skip to main content

Persistence Settings

These are Endatix API settings (Endatix:Persistence). They pick the database provider, connection strings, and migration behavior.

Configuring the Database Provider​

The easiest way to specify which database provider Endatix should use is through the configuration:

"Endatix": {
"Persistence": {
"Provider": "PostgreSql" // Or "SqlServer"
}
}

Supported providers are SQL Server and PostgreSQL. On PostgreSQL, the pg_trgm extension is required for data-list label search — see System Requirements.

SQL Server must be SQL Server 2025 or later, or Azure SQL Database: the schema uses SQL Server's native json type.

The Reporting module (Endatix:FeatureFlags:ReportingModule) runs on both providers and migrates its reporting schema at startup on either.

The Background Jobs module (Endatix:FeatureFlags:JobsModule) runs on both providers too, and migrates its jobs schema, including the job scheduler's tables, at startup on either. On SQL Server, enqueueing a job holds the scheduler's cluster-wide trigger lock until its transaction commits (Endatix:BackgroundJobs:LockOnInsert, true by default on SQL Server). Setting it to false requires READ_COMMITTED_SNAPSHOT on for the database; a node configured that way refuses to start without it. A node whose start was deferred because the database was away checks once the database is back: without it, the node stays up, logs the refusal as Critical, and fails every enqueue until it is restarted after READ_COMMITTED_SNAPSHOT is turned on. The Jobs module README explains when that trade is worth making and gives the measurements behind it.

Audience on SQL Server​

The Audience module (Endatix:FeatureFlags:PersonalizationModule) runs on both providers.

Keep READ_COMMITTED_SNAPSHOT on for the database. A database that Endatix creates on first start has it on, and so does Azure SQL Database; a database created beforehand (by a DBA or a script) may have it off. Without it, a read waits for any writer whose uncommitted rows it scans: while one tenant imports a 5,000-row CSV, another tenant's audience requests can wait 1.5–2 seconds for the import to commit. With it on, their reads do not wait; a write can still wait briefly near the end of a large import, when SQL Server escalates the import's row locks to table locks. Check and turn it on with:

SELECT is_read_committed_snapshot_on FROM sys.databases WHERE name = DB_NAME();
ALTER DATABASE CURRENT SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE;

Usage Examples​

1. Automatic Configuration with Defaults​

The simplest way to configure persistence with defaults:

// Automatically selects the provider from configuration
builder.Host.ConfigureEndatix();

2. Direct Provider Selection with Full Custom Configuration​

Complete control over persistence configuration:

// Full custom configuration
builder.Host.ConfigureEndatix(endatix => {
endatix.WithPersistence(persistence => persistence
.UseSqlServer<AppDbContext>(options => {
options.ConnectionString = "Server=myserver;Database=mydb;Trusted_Connection=True;";
options.EnableSensitiveDataLogging = true;
options.CommandTimeout = 60;
options.MaxRetryCount = 5;
})
.EnableAutoMigrations()
.EnableSampleDataSeeding());
});

3. Hybrid Approach - Defaults Plus Customization​

Start with defaults and customize only what you need:

// Hybrid approach
builder.Host.ConfigureEndatixWithDefaults(endatix => {
endatix.WithPersistence(persistence => {
// Override the connection string
persistence.UseSqlServer<AppDbContext>(options => {
options.ConnectionString = "your_custom_connection_string";
});

// Enable auto migrations
persistence.EnableAutoMigrations();
});
});

Convenience Methods​

For scenarios where you only need to configure the database context without other customizations:

// Use the convenience method for SQL Server
builder.Host.ConfigureEndatix(endatix =>
endatix.UseSqlServer<AppDbContext>());

// Use the convenience method for PostgreSQL
builder.Host.ConfigureEndatix(endatix =>
endatix.UsePostgreSql<AppDbContext>());

Available Settings​

SettingDescriptionDefault Value
Endatix:Persistence:ProviderThe database provider to use (SqlServer or PostgreSql)SqlServer
ConnectionStrings:DefaultConnectionThe default database connection stringNone
ConnectionStrings:DbProviderThe database provider to use (SqlServer or PostgreSql)SqlServer

Provider-Specific Options​

Each database provider supports additional configuration options:

SQL Server Options​

services.AddEndatix(configuration)
.UseSqlServer<AppDbContext>(options => {
options.ConnectionString = "your_connection_string";
options.MigrationsAssembly = "Your.Migrations.Assembly";
options.CommandTimeout = 30;
options.MaxRetryCount = 5;
options.MaxRetryDelay = 30;
options.EnableSensitiveDataLogging = false;
options.EnableDetailedErrors = false;
});

PostgreSQL Options​

services.AddEndatix(configuration)
.UsePostgreSql<AppDbContext>(options => {
options.ConnectionString = "your_connection_string";
options.MigrationsAssembly = "Your.Migrations.Assembly";
options.CommandTimeout = 30;
options.MaxRetryCount = 5;
options.MaxRetryDelay = 30;
options.EnableSensitiveDataLogging = false;
options.EnableDetailedErrors = false;
});

Combining with Other Settings​

You can combine persistence configuration with other Endatix features using the builder pattern:

services.AddEndatix(configuration)
.UseSqlServer<AppDbContext>()
.EnableAutoMigrations()
.EnableSampleDataSeeding()
.Api.AddSwagger().Build()
.Security.UseJwtAuthentication().Build();
Note

Database connection strings should be stored securely using secrets management in production environments.