Choosing the Right Multi-tenancy Model

An easy approach with example, comparisons, and personal experience notes.

Michael (Te Kai) Chen
5 min readAug 18, 2024

When building software-as-a-service(SaaS), one of the most important architectural decisions revolves around the choice of multi-tenancy models. This decision affects everything from cost and performance to data security and compliance. Here is how I would approach it.

Example Scenario

Let’s imagine a SaaS platform that provides services for businesses. Each company that signs up for the service will be a tenant on the platform. These companies will want to manage their users and data independently of each other. Additionally, they will have varying levels of activity — some companies might use the platform heavily, while others might only use it sporadically.

Key requirements for the project include:

  • Data Isolation: Each company’s data should be kept completely separate from others.
  • Scalability: The platform should be able to handle an increase in tenants without a significant rise in costs or complexity.
  • Cost Efficiency: You want to minimize infrastructure costs, especially in the early stages when the number of tenants is relatively low.
  • Performance: High activity from one tenant should not negatively impact the experience for others.
  • Customization: Some companies might request specific features or custom workflows.

Options

Single-Tenant Model

The appeal of the single-tenant model was immediate — complete data isolation for each customer. This model allows for a high degree of customization and guarantees that one tenant’s performance issues won’t affect others. It’s would be a go-to for applications that need to meet stringent compliance requirements or where customers demand bespoke solutions.

However, the downsides are quite apparent as well. The infrastructure costs are significantly higher, as each tenant requires its own instance of the application and database. This also makes maintenance more complex, especially as the number of tenants grows. It’s like having multiple isolated islands that each need their own resources, which can be overkill for smaller or less demanding clients.

Shared Everything Model

On the other end of the spectrum is the shared everything model, where all tenants share the same application instance and database schema.

This model is incredibly cost-efficient, making it easier to scale by simply adding more instances. Maintenance is simplified too — only one codebase and one database schema to manage.

But with these benefits come with risks. Data isolation is minimal by default — implemented at the application level and checked at every query. This increases the potential for data leaks between tenants. Role-based access control (RBAC) and encryption need to be meticulously implemented to ensure data security. Also, performance can degrade if one tenant’s usage spikes, impacting others. Caching strategies and load balancing also require careful planning to prevent one tenant’s actions from affecting others.

In short, this model falls short for applications where security and performance isolation are critical.

Shared Database with Separate Schemas

Here, all tenants share a database instance, but each has its own schema.

This provides better data isolation compared to a fully shared schema, and it allows for some level of customization. This model is more complex than a shared everything approach, but it offers some balance of cost efficiency and data isolation.

We’re still dealing with the same issue where a hyperactive tenant could bottleneck other tenants. Maintaining the data for each tenant could also get unwieldy as the number of tenants and users grow. Backup and restore would normally cover the entire database, which is a good thing and a bad thing depending on the situation.

Shared Application with Separate Databases

Then there’s the shared application with separate databases model, which offers a strong level of data isolation without the full cost burden of single-tenancy. Each tenant has its own dedicated database while sharing the same application instance. This allows for tenant-specific database tuning and customization. And considering the most common bottleneck for web services is at the database, this will serve to prevent one hyperactive tenant from affecting others significantly. In this model, we can easily enable, disable, backup, delete, and restore each tenant separately and quite intuitively.

The trade-off, however, is higher infrastructure costs and increased complexity in managing multiple databases. There would need to be robust application-layer logic to switch between database connections based on the tenant making the query.

This model shines in scenarios where data privacy is a concern and in SaaS products, especiallyy when we can’t predict each tenant’s activity.

Isolation in Shared Architecture

There are a couple of ways to achieve isolation when one or more resources are shared. The very first thing we need to consider is how to identify each tenant. Some of the common ways to achieve this is by using subdomain (example: tenant1.yoursaas.com/*) or path (example: yoursaas.com/tenant1/*). In either case, we need to extract the identifier and use it to differentiate DB queries and connections.

For SPA or Hybrid Frameworks

In the case of frameworks like React, Vue, Next, Nuxt, Sveltekit, etc. we need a way to reliably pass the tenant identifier from the frontend. The backend would then extract and validate the identifier, using it to either make the correct queries or point to the correct DB connection.

My SaaS Project

The example scenario reflects one of my recent projects. I needed to choose between different tenancy models to balance cost, complexity, and security. The project is a B2B SaaS, where each tenant has their own users and data that need isolation from others. Data isolation and security were top priorities, though there were no strict regulatory requirements to meet.

Given that the product is niche with a relatively low expected number of tenants and throughput, I wanted to avoid over-investing in infrastructure.

Decision-Making Process

  1. Single-Tenant Model: Great for data isolation, but the high infrastructure cost and maintenance complexity made it overkill for this project.
  2. Shared Everything Model: Cost-effective and simple to maintain, but data isolation was too weak, and I was concerned about one tenant’s performance affecting others. We wanted to market heavily on strong data isolation and security practices. There was also mention of doing an audit at some point.
  3. Shared Database with Separate Schemas: A bit of middle-ground, offering better isolation at a reasonable cost. However, managing multiple schemas could become a headache as the number of tenants grew. For this level of complexity, I would rather go with separate databases.
  4. Shared Application with Separate Databases: This one hit the sweet spot — strong data isolation with manageable costs. Each tenant gets their own database, reducing the risk of cross-tenant issues. It also makes it easy to manage backups and customizations per tenant. The added complexity of handling multiple databases was worth the trade-off.

Decision

Considering all that, I made the decision to start with a Shared Everything Model and slowly build toward a Shared Application with Separate Databases Model. By starting off with data isolation at the application layer, the final version app can be deployed in a Single Tenant, Shared Everything or Shared Application with Separate Databases models. That way I retain the highest level of flexibility, and also opens doors to charging different tiers for different levels of security and isolation. This step-wise approach also makes it possible for me to build quickly in the beginning and get valuable, early feedback from stakeholders and alpha testers.

--

--

Michael (Te Kai) Chen
Michael (Te Kai) Chen

Written by Michael (Te Kai) Chen

0 Followers

Avid learner. Doctor turned software engineer. Super passionate about tech and building things. Engineering Lead at https://reverehere.com

No responses yet