Skip to content

PostgreSQL

Terminal window
dotnet add package Surefire.PostgreSql
dotnet add package Npgsql.DependencyInjection

The PostgreSQL provider resolves an NpgsqlDataSource from DI. Register one with Npgsql.DependencyInjection or the Aspire client extension, then call UsePostgreSql:

builder.Services.AddNpgsqlDataSource(builder.Configuration.GetConnectionString("Surefire")!);
builder.Services.AddSurefire(options => options.UsePostgreSql());

That call wires up both the store and notifications. Notifications use PostgreSQL’s LISTEN/NOTIFY, so workers across the cluster wake up immediately when new runs are enqueued.

To resolve a keyed or named data source, pass a factory:

options.UsePostgreSql(sp => sp.GetRequiredKeyedService<NpgsqlDataSource>("surefire"));

With AutoMigrate enabled (the default), Surefire creates and migrates the required surefire_* tables on startup.

Store and notifications on separate connections

Section titled “Store and notifications on separate connections”

Some setups need different connections for the store and the notification listener. A common case is running the store through PgBouncer in transaction mode while using a direct connection for LISTEN/NOTIFY. Register two keyed data sources and wire each side independently:

options.UsePostgreSqlStore(sp => sp.GetRequiredKeyedService<NpgsqlDataSource>("store"));
options.UsePostgreSqlNotifications(sp => sp.GetRequiredKeyedService<NpgsqlDataSource>("notifications"));

LISTEN/NOTIFY is the low-latency wakeup path. PostgreSQL is always the source of truth.

  • Healthy: workers wake immediately when notifications arrive.
  • Notification connection lost: wakeups fall back to PollingInterval until the connection recovers.
  • Health checks: Surefire reports degraded health when notifications are unhealthy, even if the store itself is reachable.