Tenantry Pro
Provisioning, migrations across tenant databases, and tenant-aware operations. Pro builds on the open-source Tenantry Core, which stays free and covers resolving tenants and isolating their data on its own.
Onboard a tenant
One call creates the tenant’s database or schema, applies your migrations and runs your seeders, in order. The result reports each step: succeeded, failed, skipped or not run. Every built-in step is safe to repeat, so a failed onboarding is retried by running it again.
Tenant lifecycletenant.UsePro(pro => pro
.AddSeeder<DefaultDataSeeder>() // your seeder, last
.AddDatabaseProvisioning<AppDbContext>() // creates the database, first
.AddMigrations<AppDbContext>()); // then migrates it
var result = await provisioner.ProvisionAsync(descriptor, ct);
if (result.Succeeded)
await tenants.ActivateAsync(descriptor.TenantId, ct);Keep every tenant database migrated
Run your application with migrate-tenants as a deployment step: it applies the pending EF Core migrations to every tenant’s database or schema, one at a time or several at once, each once however many tenants share it. One database’s failure does not stop the others; each is logged, and the step fails so the release waits. The status is readable without migrating.
Tenant migrationsawait using var app = builder.Build();
// dotnet run -- migrate-tenants
if (await app.RunTenantMigrationsIfRequestedAsync(args) is { } exitCode)
return exitCode; // 1 if any database or schema failed
await app.RunAsync();
return 0;Run background work as the tenant
A Hangfire job, a Quartz.NET job, or a MassTransit or Rebus message carries the tenant it was created for, and runs as that tenant, with its DbContext isolated as in a request. Recurring work can run once for each tenant. A job whose tenant no longer exists is rejected rather than run as nobody.
Background jobstenant.UsePro(pro => pro.AddHangfirePropagation());
builder.Services.AddHangfire((sp, config) => config
.UseSqlServerStorage(connectionString)
.UseTenantry(sp));
// Runs as the current tenant, or as the one you name:
jobs.ForTenant(tenantId).Enqueue<ReportJob>(job => job.Execute());Also in Pro
Schema per tenant and mixed mode
A schema per tenant on SQL Server and PostgreSQL, or per tenant a choice of its own database, its own schema or the shared database.
Audit logging
Every insert, update and delete your contexts save, with the tenant, the time, who made it and the changed values: once committed, or in the same transaction.
Health checks and metrics
Health checks that probe every tenant database for its connection and pending migrations, and ASP.NET Core’s request metrics tagged with the tenant.
Connection-string caching
Connection strings read from a secrets store, kept for a period, so the lookup runs once per tenant rather than for every context.
Before you buy
- What does the subscription include?
- Every Tenantry Pro package, from a private NuGet feed, with each release while the subscription lasts, a licence key, and email support. One subscription, billed monthly or yearly: no tiers or seats.
- How do I install it, locally and in CI?
- Connect your GitHub account on your Pro access page, then add the feed to a nuget.config with a read-only GitHub token. In CI the token is a secret, and so is the licence key; the installation guide has the steps for GitHub Actions and Docker builds. Installation
- Which versions and databases?
- .NET 8, 9 and 10, with the EF Core of each. Provisioning and migrations on SQL Server, PostgreSQL and MySQL; schema per tenant on SQL Server and PostgreSQL. Compatibility
- Does it phone home?
- No. The licence key is checked offline when the application starts, and it does not expire. Licensing
- What happens when the subscription ends?
- The versions you have keep working, under the licence: the key keeps validating. Your access to the package feed ends, so keep copies of the packages you build with, in an internal feed or a local package folder, until you subscribe again.