Choosing your multi-tenant database architecture is a business decision
There are three common approaches to structuring data in a multi-tenant platform. Each has different characteristics, but more importantly, each creates different constraints and opportunities for the business operating the platform.
The right choice depends on far more than database performance or data isolation. It can affect how quickly you can build and release, what your customers and integrations can do, how easily the platform can evolve, how expensive it is to operate, and the engineering capability required to maintain it.
This article looks at multi-tenant database architecture from that perspective: starting with the needs of the business and using those needs to guide the technical architecture.
The multi-tenant database approaches
In this section, we will discuss the advantages and disadvantages of the three main approaches to storing multi-tenant data, along with the business requirements that may lead you to choose one over another.
Some SaaS platforms and API vendors use a combination of these approaches, which we will discuss later in the article.
There are variations in how each approach can be implemented, but this article focuses on the broader architectural and business trade-offs rather than implementation detail.
Database per tenant
In this approach, each tenant has its own database. These databases may share underlying database infrastructure, or each tenant may be given a completely dedicated database instance where stronger resource isolation is required.
The benefits include:
- Strong separation of tenant data. Application queries against one tenant's database cannot accidentally return rows belonging to another tenant.
- Security boundaries are generally simpler because application-specific queries do not need to continually filter data by tenant.
- A tenant's database can be backed up, restored, moved or potentially migrated independently.
- Individual tenants can be moved onto different infrastructure or given additional resources as their requirements grow.
- Application logic can be simpler because much of the code can operate as though it were working with a single-tenant system.
- Database costs and resource consumption can be easier to attribute to individual tenants, particularly where infrastructure is dedicated.
If tenants are given dedicated database infrastructure, there are additional benefits:
- Database compute, memory and I/O are isolated from other tenants.
- A particularly busy tenant cannot create a database-level noisy-neighbour problem for other tenants.
- Database resources can be sized and optimised specifically for that tenant.
The main disadvantages are:
- Operational complexity increases with the number of tenants. Databases must be provisioned, monitored, backed up and maintained.
- If dedicated database infrastructure is provided for each tenant, infrastructure costs can increase almost linearly with tenant count.
- Database migrations need to be applied across every tenant database. At large tenant counts this requires good automation, migration tracking and handling of partial failures.
- Database versions can potentially drift if migrations do not complete successfully across every tenant.
- Queries spanning multiple tenants become considerably more complicated. Reporting, search or integrations requiring data from many tenants may require querying multiple databases and combining the results elsewhere.
- Connection management can become increasingly complicated as the number of tenant databases grows.
- Provisioning new tenants can be slower and more operationally complex, because a new database may need to be created, configured, secured, monitored and added to deployment or migration workflows.
- As the number of tenants increases, the software becomes increasingly harder to change at a table level due to the number of migrations that must occur. Even relatively simple structural changes can become significant deployment exercises because they must be successfully applied across every tenant database.
When does database-per-tenant make sense?
This approach becomes particularly attractive when:
- Customers require strong data separation.
- Individual tenants are large enough that the cost of dedicated infrastructure is relatively insignificant.
- Tenant workloads vary considerably and some tenants may need to scale independently.
- Tenant-level backup, restore, export or migration is important.
- The number of tenants is relatively small or operational tooling is sophisticated enough to manage a large database fleet.
- Cross-tenant queries are uncommon.
- The application contains substantial business logic and keeping tenant isolation out of that logic materially simplifies development.
- The engineering team wants a simpler application-level security model and is prepared to accept greater operational complexity.
- You want to get moving quickly with one client and not have the overhead of managing multi-tenancy in the code.
Shared database, shared schema
In this approach, tenant data is stored in shared tables within a single database. Tenant isolation is usually achieved either by storing a tenant identifier on tenant-owned records, or by deriving which tenant a record belongs to through its relationships with other tables.
The benefits of this approach include:
- Cross-tenant functionality is generally easier to support, including users or services that need to access data belonging to multiple tenants within the same operation.
- Database infrastructure costs are shared, making the marginal infrastructure cost of adding another tenant relatively small.
- Database scaling, backup, monitoring and migrations are performed against a much smaller number of database systems.
- Enables richer user experiences across tenants. For example, a user with access to several tenants could retrieve a combined list of tasks and sort them by priority, rather than having to work through each tenant separately.
- Platform-level reporting and integrations that operate across tenants are generally easier to implement.
- Provisioning a new tenant can be as simple as creating the appropriate tenant records rather than provisioning new database infrastructure.
- Database connections, tables and indexes are shared across tenants, which can make efficient use of database resources.
The disadvantages include:
- Application and data-access logic is more complex because every operation must correctly enforce tenant isolation.
- A mistake in tenancy or authorisation logic can potentially expose or modify another tenant's data.
- Tenant workloads share database resources. Expensive queries or unusually high activity from one tenant can therefore affect others.
- Scaling a particularly demanding tenant independently is more difficult than with a database-per-tenant architecture.
- Backing up, restoring, exporting or moving an individual tenant is more complicated because its data is mixed with data belonging to other tenants.
- As the combined dataset grows, tables and indexes can become very large, making database design, indexing and query performance increasingly important.
- Some customers or regulatory environments may require stronger separation than a shared database provides.
When does a shared database, shared schema make sense?
This approach is particularly attractive when:
- You want to minimise infrastructure costs and keep the incremental cost of adding new tenants low.
- You want to reduce DevOps, database administration and ongoing operational overhead.
- Your engineering team has the capability to reliably enforce tenant isolation within shared tables.
- Tenant workloads are reasonably predictable, or you have controls in place to prevent one tenant from materially affecting others.
- Users, services or integrations need to work across multiple tenants seamlessly.
- Your application requires interaction between tenants, and you want that interaction to occur directly within the platform's data model rather than through separate inter-tenant interfaces.
- You need platform-wide search, analytics or reporting across multiple tenants.
- Customers do not require their data to be stored in a physically or logically separate database.
- You do not have a strong requirement to back up, restore or migrate individual tenants independently.
- You expect to have a large number of tenants, where operating a separate database for every tenant would create disproportionate cost or operational complexity.
Frameworks can materially reduce some of the trade-offs of a shared-database, shared-schema architecture, particularly by reducing project setup time and removing the need to write custom application code for standard CRUD routes. Developers can then focus more of their time on application-specific business logic, including the more complex cases that span multiple tables or require custom tenancy-aware behaviour. This substantially reduces the risk surface by limiting the amount of bespoke multi-tenant code that needs to be written and maintained. One example of this approach is CustomAPIs.
Single database, separate schema per tenant
In this approach, each tenant's data is stored in its own schema while sharing the resources of the same database. Each tenant has its own set of tables, providing a clear logical separation between tenant data.
Because the schemas exist within the same database, queries can still reference tables across multiple schemas where required. This can provide some of the cross-tenant capabilities of a shared-database, shared-schema architecture, although the application must explicitly know which schemas it needs to access.
Schema-per-tenant therefore sits somewhere between the two approaches described above. It provides stronger separation of tenant data than shared tables while retaining much of the infrastructure efficiency of a shared database. As we will see, however, it also inherits some of the operational and application complexity.
The benefits of this approach include:
- Strong logical separation of tenant data. Queries operating within one tenant's schema will not normally return rows belonging to another tenant unless another schema is explicitly referenced or the connection is incorrectly configured.
- Application-level tenant isolation can be simpler. Business queries generally do not need to include a tenant identifier on every operation.
- Database infrastructure costs are shared, making the marginal infrastructure cost of adding a tenant substantially lower than providing dedicated database infrastructure for every tenant.
- Database connections and underlying resources can be shared across tenants.
- Tenant data can be exported, restored or migrated independently more easily than with shared tables. Database tooling can operate against an individual schema, although shared dependencies may complicate this.
- Moving an individual tenant to another database is comparatively straightforward because its tables are already separated from those of other tenants.
- Platform-level reporting and integrations across tenants remain possible, as schemas exist within the same database.
- Application business logic can often operate much like a single-tenant application, with the tenant's schema establishing the data boundary.
- Tables and indexes remain smaller per tenant, which can be advantageous for some workloads compared with extremely large shared tables.
The disadvantages of this approach include:
- Operational complexity increases with tenant count. Every tenant introduces another collection of tables and other database objects that must be provisioned and maintained.
- Schema migrations must be performed across every tenant schema. At large tenant counts this requires reliable automation, migration tracking and handling of partial failures.
- Tenant schemas can drift between versions if migrations fail or are only partially completed.
- As the number of tenants grows, table-level changes become progressively harder to deploy. A change that would require a single migration in a shared-schema model may need to be applied hundreds or thousands of times across tenant schemas. This increases deployment time, rollback complexity, the chance of partial failure, and the amount of tooling required to verify that every tenant has been upgraded successfully.
- Very large numbers of schemas and database objects can create management and database-catalog overhead. This can affect migrations, tooling, metadata operations and eventually database performance.
- Cross-tenant queries are more complicated than with shared tables. The application may need to dynamically address multiple schemas, construct unions or otherwise coordinate queries across tenant datasets.
- Provisioning a new tenant is more involved than simply inserting a tenant record, because a schema and its associated tables, indexes and initial data must be created.
- Tenant workloads share database resources. A computationally expensive query or heavy workload from one tenant can affect the performance of others.
When does schema-per-tenant make sense?
This approach becomes particularly attractive when you want strong logical separation between customers but do not want the infrastructure cost of a separate database for every tenant.
It can be a particularly good fit when:
- Customers may eventually need to move onto dedicated infrastructure.
- Tenant-level export, migration or restore is important.
- Cross-tenant operations exist but are relatively uncommon.
- Keeping tenancy out of normal business queries materially simplifies development.
- You want to get an initial customer running without designing tenancy into every table and query.
- You expect the combination of tenant count × tables per tenant to remain operationally manageable.
Combining approaches future-proofs the platform
Multi-tenant platforms do not necessarily need to use the same database architecture for every tenant.
Many platforms begin with either a shared database with a shared schema or a shared database with a separate schema per tenant. These approaches allow infrastructure and operational costs to be shared across customers while preserving the option to move particular tenants onto dedicated database infrastructure later.
This can be useful when a customer grows significantly, develops unusually high resource requirements, or requires stronger data isolation for commercial, security or compliance reasons.
Regional data-residency requirements can also lead to platforms using shared infrastructure within each region rather than requiring a separate database for every tenant.
Moving in this direction — from shared infrastructure toward dedicated infrastructure — is generally easier than moving the other way. A tenant whose ownership boundaries are clearly defined can often be extracted from shared infrastructure and routed to its own database. Moving from a database-per-tenant architecture back toward shared tables can require much more fundamental changes to the data model, tenancy enforcement, authorisation and application logic.
For this reason, the ability to evolve the tenancy model over time can itself be an important architectural consideration.
The questions that need answering
There is no single multi-tenant database architecture that is best for every business. The appropriate choice depends on the requirements of your customers, the characteristics of your product, and the capabilities of the team building and operating it.
From a customer and business perspective, consider:
- How cost-sensitive are your customers?
- What level of data isolation, security or compliance do they require?
- Do customers have data-residency requirements that require their data to remain within particular countries or regions?
- Do users or integrations need to access or update data across multiple tenants in a single operation or session?
- Is tenant-level backup, restore, export or migration important?
- Are some customers likely to require dedicated infrastructure?
- What performance or availability guarantees do customers expect?
From an internal and operational perspective, consider:
- What DevOps, database and automation capabilities does your team have?
- How many tenants are you likely to support?
- How many tables and other database objects will exist per tenant?
- How frequently is the data model likely to change?
- How important is rapid deployment of schema changes?
- How quickly do you need to reach a working product?
- Does the engineering team have the depth required to safely implement and maintain tenant isolation in shared infrastructure?
- How much ongoing operational complexity can the business afford to carry?
From a product and workload perspective, consider:
- Do you have large or unpredictable workloads that could affect other tenants?
- Do you need cross-tenant search, reporting or analytics?
- Are relationships between tenants an important part of the product?
- Do some tenants have dramatically different data volumes or performance requirements?
- Is the product likely to evolve toward more complex tenancy relationships over time?
Comparing multi-tenant database architectures
| Consideration | Database per tenant | Schema per tenant | Shared schema |
|---|---|---|---|
| Marginal cost per tenant | High | Low | Very low |
| Data isolation | Very strong | Strong logical separation | Must be enforced |
| Cross-tenant access | Difficult | Possible, but cumbersome at scale | Natural |
| Tenant-level backup/restore | Strong | Good | More difficult |
| Independent tenant scaling | Strong | Limited | More difficult |
| Schema change at high tenant counts | Difficult | Potentially very difficult | Relatively simple |
| Operational overhead | High | Medium–high | Lower |
| Application tenancy complexity | Low | Low–medium | High |
| Suitability for very large tenant counts | Depends heavily on automation | Can become problematic | Strong |
| Noisy-neighbour isolation | Strong if dedicated infrastructure | Limited | Limited |
| Moving tenant to dedicated DB later | Already isolated | Relatively straightforward | Possible if designed for it |
Architecture should fit your business
There is no universally correct multi-tenant database architecture, only one that fits your business at the time you make the decision. Start with what your customers need, what your team can realistically operate, and where the product is likely to go over the next few years, and let those answers drive the technical choice rather than the other way around.
Whichever approach you choose, think about how it may need to evolve. A tenant that is small today may eventually require dedicated infrastructure, stronger isolation or significantly more resources. Cross-tenant reporting, integrations and relationships may also become more important as the product grows. Designing with those possibilities in mind is generally much easier than trying to retrofit them once the platform is established.