
We put on another Critter Stack live stream today to give a highlight tour of the multi-tenancy features and support across the entire stack. Long story short, I think we have by far and away the most comprehensive feature set for multi-tenancy in the .NET ecosystem, but I’ll let you judge that for yourself:
The Critter Stack provides comprehensive multi-tenancy support across all three tools — Marten, Wolverine, and Polecat — with tenant context flowing seamlessly from HTTP requests through message handling to data persistence. Here’s some links to various bits of documentation and some older blog posts at the bottom as well.
Marten (PostgreSQL)
Marten offers three tenancy strategies for both the document database and event store:
- Conjoined Tenancy — All tenants share tables with automatic
tenant_iddiscrimination, cross-tenant querying viaTenantIsOneOf()andAnyTenant(), and PostgreSQL LIST/HASH partitioning ontenant_id(Document Multi-Tenancy, Event Store Multi-Tenancy) - Database per Tenant — Four strategies ranging from static mapping to single-server auto-provisioning, master table lookup, and runtime tenant registration (Database-per-Tenant Configuration)
- Sharded Multi-Tenancy with Database Pooling — Distributes tenants across a pool of databases using hash, smallest-database, or explicit assignment strategies, combining conjoined tenancy with database sharding for extreme scale (Database-per-Tenant Configuration)
- Global Streams & Projections — Mix globally-scoped and tenant-specific event streams within a conjoined tenancy model (Event Store Multi-Tenancy)
Wolverine (Messaging, Mediator, and HTTP)
Wolverine propagates tenant context automatically through the entire message processing pipeline:
- Handler Multi-Tenancy — Tenant IDs tracked as message metadata, automatically propagated to cascaded messages, with
InvokeForTenantAsync()for explicit tenant targeting (Handler Multi-Tenancy) - HTTP Tenant Detection — Built-in strategies for detecting tenant from request headers, claims, query strings, route arguments, or subdomains (HTTP Multi-Tenancy)
- Marten Integration — Database-per-tenant or conjoined tenancy with automatic
IDocumentSessionscoping and transactional inbox/outbox per tenant database (Marten Multi-Tenancy) - Polecat Integration — Same database-per-tenant and conjoined patterns for SQL Server (Polecat Multi-Tenancy)
- EF Core Integration — Multi-tenant transactional inbox/outbox with separate databases and automatic migrations (EF Core Multi-Tenancy)
- RabbitMQ per Tenant — Map tenants to separate virtual hosts or entirely different brokers (RabbitMQ Multi-Tenancy)
- Azure Service Bus per Tenant — Map tenants to separate namespaces or connection strings (Azure Service Bus Multi-Tenancy)
Polecat (SQL Server)
Polecat mirrors Marten’s tenancy model for SQL Server:
- Conjoined Tenancy — Shared tables with
tenant_idcolumn and composite primary keys, automatic query filtering (Document Multi-Tenancy, Event Store Multi-Tenancy) - Database per Tenant — Dedicated SQL Server database per tenant with independent schema management and async daemon processing (Database-per-Tenant Configuration)