Back to blog

Multi-tenant SaaS foundations with Finbuckle.MultiTenant

Tenant resolution, per-tenant configuration, and data isolation are the load-bearing walls of any SaaS. Here is how we build them on .NET with Finbuckle.MultiTenant.

Engineering
May 8, 2026 10 min read
Multi-tenant SaaS foundations with Finbuckle.MultiTenant

Every SaaS makes a decision about tenancy whether it means to or not. Get it right early and tenants are a column, a connection, and a config lookup. Get it wrong and you are retrofitting isolation into a system that assumed a single customer - one of the most expensive refactors there is. On .NET, Finbuckle.MultiTenant gives you the primitives to get it right from the start.

Three problems, one library

Multi-tenancy is really three problems wearing a trench coat:

  1. Resolution - given a request, which tenant is this?
  2. Configuration - what settings, branding, and limits apply to that tenant?
  3. Isolation - how do we guarantee one tenant never sees another's data?

Finbuckle addresses all three with a tenant context that it resolves per request and flows through the rest of the pipeline.

Resolving the tenant

Resolution strategies are pluggable. The common ones are host (each tenant gets a subdomain), route (a path segment), or header. Register the strategy and a store that knows your tenants:

CSHARP
builder.Services.AddMultiTenant<AppTenantInfo>()
    .WithHostStrategy()
    .WithConfigurationStore();

The AppTenantInfo is your own type - extend it with whatever a tenant needs to carry: a connection string, a plan tier, feature flags, a brand palette.

Per-tenant configuration

Once resolved, the tenant info is available through dependency injection anywhere downstream. That turns per-tenant behavior into a property read rather than a special case scattered through the code:

CSHARP
public sealed class ReportLimiter(IMultiTenantContextAccessor<AppTenantInfo> accessor)
{
    public int MaxRows => accessor.MultiTenantContext.TenantInfo?.PlanTier switch
    {
        "enterprise" => 1_000_000,
        "team" => 100_000,
        _ => 10_000,
    };
}

This is the part teams underestimate: most of what makes tenants different is configuration, and centralizing it here keeps the difference out of your domain logic.

Data isolation strategies

Isolation is where the real architecture decision lives, and Finbuckle supports the spectrum:

  • Shared database, shared schema - a TenantId column on every table, with a global query filter so you physically cannot forget the where clause. Cheapest to run, requires the most discipline.
  • Shared database, separate schema - more isolation, moderate cost.
  • Database per tenant - the strongest isolation and the easiest compliance story, resolved by swapping the connection string from the tenant info.

With EF Core, the shared-schema approach leans on a query filter that Finbuckle wires from the ambient tenant:

CSHARP
modelBuilder.Entity<Invoice>()
    .HasQueryFilter(i => i.TenantId == _tenantId);

Warning: A global query filter is a safety net, not a license to be careless. Raw SQL and certain bulk operations bypass it - audit those paths explicitly.

Picking a strategy

There is no universally right answer, only trade-offs. Shared schema scales to many small tenants cheaply but concentrates blast radius. Database-per-tenant is simpler to reason about and easier to certify, but it costs more to operate and complicates cross-tenant analytics. A common middle path - and the one we often recommend - is shared schema for the long tail and dedicated databases for large or regulated tenants, all behind the same Finbuckle abstraction so the application code does not change.

Wrapping up

Multi-tenancy stops being scary when you separate its three concerns and let a library carry the ambient tenant for you. Finbuckle handles resolution and isolation cleanly, which frees you to make the one decision that actually matters - your isolation strategy - deliberately rather than by accident. Decide it before your first paying tenant, and the rest is configuration.

Building a multi-tenant platform and weighing the isolation trade-offs? Let's discuss your architecture.

Keep reading

The four pillars of ConnectSoft: Factory, Platforms, Squads, and Marketplace
Company News
June 20, 2026 8 min read

The four pillars of ConnectSoft: Factory, Platforms, Squads, and Marketplace

ConnectSoft is more than a services company. Here is how four reinforcing lines - the AI Factory, live platforms, AI squads, and a marketplace - fit together into one ecosystem.

Read more
The ConnectSoft tech landscape: the stack behind our delivery
Company News
June 18, 2026 8 min read

The ConnectSoft tech landscape: the stack behind our delivery

A tour of the technologies we lean on across delivery - .NET and Blazor, Azure, messaging, data, observability, and AI - and the principles that decide what makes the cut.

Read more
Why we standardized on the Microsoft Agent Framework
Engineering
June 14, 2026 9 min read

Why we standardized on the Microsoft Agent Framework

Choosing the runtime for an autonomous agent mesh is a long-lived bet. Here is the reasoning behind picking the Microsoft Agent Framework, with MCP tools and a model abstraction at its core.

Read more

Subscribe to our newsletter

Get the latest tech insights straight to your inbox

Ready to work with us?

Let's discuss how our team can help achieve your digital goals