Executive Summary

A digital health product that grows past a handful of customers eventually has to decide how to host them. The two ends of the spectrum are clear. At one end, every customer gets their own backend deployment (single-tenant). At the other end, every customer shares the same backend deployment (multi-tenant, often called shared-everything). Most production deployments end up between the two, with one of three middle patterns: shared infrastructure with separate databases, shared databases with separate schemas, or shared schemas with tenant-scoped rows.

Each pattern has a clear cost profile and a clear risk profile. Choosing the wrong pattern for a given customer mix produces either an operationally unsustainable footprint or a regulatory exposure that a sufficiently careful auditor will find. This paper walks through the patterns, the cost and risk profiles, and the failure modes the patterns are exposed to.

The audience is engineering and security leads of digital health products who are designing or revisiting their tenancy architecture. The paper assumes familiarity with FHIR, with the regulated-product context that tends to drive the tenancy decision, and with general distributed systems concepts.


1. The Five Patterns

The patterns are best framed by what is shared and what is separated.

Pattern 1: Single-tenant deployment. Every customer has their own backend deployment, with their own infrastructure, database, and configuration. Nothing is shared.

Pattern 2: Shared infrastructure, separate databases. Customers share the application servers and the operational tooling but each has their own database.

Pattern 3: Shared databases, separate schemas. Customers share the database server but each has their own schema (or equivalent isolation construct, depending on the database).

Pattern 4: Shared schemas with tenant-scoped rows. Customers share the database and the schema, but every row carries a tenant identifier and queries are scoped to the tenant.

Pattern 5: Shared everything. No tenant separation. The backend serves a single logical tenant; multi-tenancy is handled at the application layer above the backend (typically through user-level access control alone).

The first four are tenancy patterns in the conventional sense. The fifth is technically not a tenancy pattern but shows up often enough to deserve naming, particularly in early-stage products where the team has not yet realised they need a tenancy model.


2. Cost Profile

2.1 Single-tenant deployment

The most expensive pattern at scale. Each customer adds a fixed operational footprint: a deployment to manage, a database to back up, a set of metrics to monitor, a release to coordinate. The cost grows linearly with customer count.

The cost is justifiable for a small number of high-value customers (large hospital systems, payers, government deployments) where the operational overhead is small relative to the contract value. The cost becomes prohibitive for products with many small customers.

2.2 Shared infrastructure, separate databases

Less expensive than fully single-tenant. The application servers and the operational tooling are shared; only the database is per-tenant. The cost grows sub-linearly with customer count because the application footprint is amortised.

The cost crossover with shared schemas is typically in the hundreds of customers, depending on the database’s per-customer overhead.

2.3 Shared databases, separate schemas

Reduces the per-customer database overhead by sharing the database server. The cost is similar to shared infrastructure with separate databases at small scale and lower at large scale.

The pattern’s downside is operational: every customer-affecting change to the database (schema migrations, index changes, backup procedures) has to handle the multiplicity of schemas.

2.4 Shared schemas with tenant-scoped rows

The least expensive pattern at scale. Every customer adds rows but no operational footprint. The cost grows roughly linearly with the data volume but with no per-customer overhead.

The pattern’s challenge is correctness. Every query has to be tenant-scoped; a missing scope means data from one customer leaks into another customer’s response. The challenge is bounded but not trivial.

2.5 Shared everything

The cheapest pattern in absolute terms. There is nothing to multiply. The pattern is appropriate only for products where the customer is in fact a single logical tenant; if the customer is many real tenants pretending to be one, the pattern produces the worst of all worlds (the cheapest cost profile and the highest risk profile).


3. Risk Profile

3.1 Cross-tenant data leakage

The dominant risk in a multi-tenant FHIR backend is cross-tenant data leakage: a query from one customer returns data belonging to another. The risk grows as the tenant-scope check moves from the infrastructure layer to the application layer.

Single-tenant deployments and shared-infrastructure-with-separate-databases patterns push the tenant-scope check to the infrastructure layer. The check is a property of the deployment; a leak requires a wrong deployment, not a wrong query.

Shared schemas with tenant-scoped rows push the tenant-scope check to the query. Every query has to add the scope; a missing scope is a leak. The mitigation is to centralise the scope in the data-access layer so the check is a property of the system rather than a property of each query.

3.2 Noisy-neighbour incidents

A heavy-load tenant on a shared deployment can degrade the service for other tenants. The risk grows as the workload isolation moves from the infrastructure layer to the application layer.

The mitigation is workload isolation at the layer where the tenancy is shared: per-tenant resource quotas at the database level, per-tenant rate limits at the application level, per-tenant connection pools at the connection level.

3.3 Blast radius of a security incident

A security incident in a single-tenant deployment affects one customer. A security incident in a shared-everything deployment affects all customers. The intermediate patterns sit on a continuum.

The mitigation is to limit the surface that is shared across tenants. A shared application server with separate databases limits the blast radius of an application-layer incident. A shared everything pattern offers no such limit.

3.4 Regulatory exposure

Some regulatory frameworks (DiGA, certain hospital procurements, certain payer contracts) require deployment-level isolation. A shared deployment that the contract requires to be single-tenant is a contractual breach regardless of the technical correctness of the access boundary.

The mitigation is to know the regulatory and contractual requirements per customer up front and to assign them to the appropriate tenancy pattern.

3.5 Backup and recovery scope

Backup and recovery scope follows the database scope. A separate-database pattern allows per-tenant backup and recovery; a shared-database pattern requires per-tenant restore to be carved out of a shared backup. The carving is technically possible but operationally complex.

The mitigation is to align the backup and recovery scope with the customer’s expected restore scenarios.


4. The FHIR-Specific Pitfalls

The general multi-tenancy patterns above apply to any backend. FHIR adds some specific pitfalls.

4.1 Cross-tenant references

A FHIR Reference is a string identifier that points to another resource. In a multi-tenant deployment with shared resource IDs, a reference can technically point to a resource in another tenant.

The mitigation is per-tenant ID namespaces or globally-unique IDs. Per-tenant ID namespaces require the search to scope by tenant before resolving references; globally-unique IDs (typically UUIDs) make the cross-tenant reference visible if it occurs.

A FHIR search that does not include the tenant scope as a filter parameter will return results from all tenants. Leaving the tenant scope as an optional search parameter fails sooner or later; injecting the tenant scope at the search-resolution layer keeps it always present.

4.3 Bulk Data export scope

A FHIR Bulk Data export that does not respect tenant boundaries can produce a dataset that crosses tenants. Evaluating the bulk export against the entire database and filtering post-hoc invites cross-tenant leakage; scoping the export job at job creation and evaluating against the scoped dataset keeps the boundary intact.

4.4 Subscription delivery scope

A FHIR Subscription delivers events from one tenant to a destination registered by another tenant if the subscription is not tenant-scoped. Scope subscription evaluation by the tenant that owns the subscription, and ensure the destination URLs are per-tenant.

4.5 ID-uniqueness assumptions

Some FHIR profiles assume globally-unique resource IDs. In a multi-tenant deployment with per-tenant ID namespaces, the assumption fails. The mitigation is to use globally-unique IDs (UUIDs) for resources that participate in such profiles, or to handle the ID translation explicitly at the integration boundary.


5. Patterns That Work

The patterns that survive an audit and remain operationally sustainable share a small number of properties.

5.1 Tenant scope at the data-access layer

The tenant scope is enforced at the data-access layer, not at the application code that orchestrates the request. The application code cannot construct a query that bypasses the scope; the scope is a property of the data-access layer.

The mechanism is typically the same rule chain that enforces user-level authorization. The tenant scope is a rule that always applies; user-level rules apply on top of it.

5.2 Audit by tenant

Audit records are tagged with the tenant. A patient-side or regulator-side access-log query is per-tenant by construction. The audit storage may or may not be per-tenant; the records are.

5.3 Per-tenant secrets

Secrets that affect a tenant (encryption keys, integration credentials, signing keys) are per-tenant. A leaked secret affects one tenant, not all of them.

5.4 Per-tenant configuration

Per-tenant configuration (feature flags, integration toggles, branding, regional settings) is stored per-tenant. The application code reads the configuration through a per-tenant accessor; there is no global configuration that mixes tenants.

5.5 Tenant lifecycle as a first-class operation

Tenant creation, tenant suspension, tenant deletion, and tenant export are first-class operations supported by the backend’s tooling. The operations are scriptable, auditable, and reversible. Customers come and go; the lifecycle has to be a routine rather than a project.


6. The Hybrid Pattern That Often Wins

The pattern that wins in many production deployments is hybrid: shared infrastructure for most customers, with the option to deploy a customer to dedicated infrastructure when their contract requires it. Two characteristics make the hybrid work.

The first is that the tenancy model is the same in both deployments. A customer on the shared infrastructure runs against the same data model, the same access boundary, and the same tooling as a customer on dedicated infrastructure. Moving a customer between the two is a deployment operation, not a re-architecture.

The second is that the dedicated infrastructure is operationally consistent with the shared infrastructure. The same release pipeline, the same monitoring, the same security baseline, the same audit shape. The dedicated deployment does not become a snowflake.

A hybrid that violates either characteristic tends to drift over time into a fork-everywhere situation that is more expensive to operate than either pure pattern.


7. Migration Patterns

Tenancy migrations are common as products grow. Three migrations show up most often.

7.1 From shared everything to tenant-scoped

The first realisation that the shared-everything model is not enough comes when the product takes on its second customer who is materially different from the first. The migration introduces a tenant identifier on every record and a tenant-scope rule at the access boundary.

The migration is mechanically straightforward but operationally large. Every record has to be backfilled with a tenant identifier; every query has to be reviewed for scope; every test has to be reviewed for tenant assumptions. Introduce the scope behind a feature flag, run with both shapes in parallel until the new shape is verified, and then remove the old shape.

7.2 From shared schema to separate database

The second migration happens when a customer’s contractual or regulatory requirements force database-level isolation. The migration extracts the customer’s data into a new database, points the customer’s traffic at the new database, and removes the customer’s records from the shared database.

Support both shapes in the data-access layer simultaneously, so the application code does not need to change for the migration.

7.3 From single-tenant to shared

The reverse migration is rare but happens when a customer’s contract changes (an acquisition, a renegotiation, a cost-driven consolidation). The migration is mechanically the inverse of the previous case.


8. Where Teams Most Often Get Stuck

Across multi-tenant FHIR backend audits and incidents, three issues account for most of the time-sinks.

8.1 Tenant scope as a query parameter

The pattern of treating the tenant scope as a query parameter that the application code adds to each query is the dominant source of leakage incidents. The scope is correct in most queries, missing in one, and the missing query is the leak.

Fix: enforce the tenant scope at the data-access layer.

8.2 Cross-tenant references through assumed-unique IDs

The pattern of assuming resource IDs are unique across tenants creates cross-tenant reference resolution that returns wrong-tenant data. The leakage is subtle and often surfaces only after a customer with overlapping IDs joins the deployment.

Fix: use globally-unique IDs or per-tenant ID namespaces.

8.3 Bulk operations that bypass the scope

Bulk operations (Bulk Data export, scheduled jobs, analytics pipelines) that bypass the per-request scope produce cross-tenant outputs. The fix is to extend the scope mechanism to bulk operations as a first-class case.


9. Closing

Multi-tenancy decisions in a FHIR backend are unusually consequential. The cost profile drives the operational sustainability; the risk profile drives the regulatory exposure. The patterns that survive both pressures are the ones that put the tenant scope at the data-access layer, that treat tenant lifecycle as a first-class operation, and that align the deployment shape with the customer’s contractual requirements.

Most successful digital health products converge on a hybrid pattern over time. The pattern is operationally sustainable, regulatorily defensible, and adaptable to customer mix changes. The architectural discipline that makes the hybrid work is the same discipline that makes the pure patterns work; the hybrid just exercises it on more cases at once.


References