In the world of software as a service (SaaS) and online web applications as well as multi-user and multi-organization applications on mobile, cloud and IoT, there is a need for every software architect or lead developer to work to define the best implementation strategy and architecture that best fits the needs of their customers, users and the business requirements.
As a consequence of the current shift of on-premises software to the cloud, software architects find themselves facing numerous new challenges related to the adequacy of architectures for cloud software. A commonly used technique in architecting for Software-as-a-Service (SaaS) is the use of the concept of multi-tenancy, which is defined in this cited in this research paper as “a property of a system where multiple varying customers and their end-users share the system’s services, applications, databases, or hardware resources, with the aim of lowering costs”.
A multi-tenant architecture has the benefit of scalability as well as security and in some cases data isolation which can help software companies meet stringent regulations such as HIPPA for health care data.
Many software architects and new developers joining the ranks of the programming world struggle to understand the patterns and best practices as well as solutions that can help them in enabling a scalable and secure multi-tenant solution. Whether working with a Ruby on Rails application, ASP.NET, Python, Java, PHP or any other programming language and framework architecture, multi-tenancy done wrong can be a major source of ‘technical debt’ as well as a risk as related to regulatory compliance, privacy, security and lastly a damaged reputation, loss of customer trust and financial losses.
When designing a multi-tenant SaaS application, you must carefully choose the tenancy model that best fits the needs of your application. A tenancy model determines how each tenant’s data is mapped to storage. Your choice of tenancy model impacts application design and management. Switching to a different model later is sometimes costly.
If you’re looking for guidance or solutions in creating, transforming or growing your multi-tenant SaaS application, we’d be happy to talk and help your team. Let’s talk!
The following comparison cited from Microsoft as a general overview of multi-tenancy architecture as well as the references at the end of the post are great resources for anyone looking for more information on general strategies, patterns and approaches towards multi-tenancy within an application. Additional references to Rails and ASP.NET multi-tenancy resources are listed at the end.
A. How to choose the appropriate tenancy model
In general, the tenancy model does not impact the function of an application, but it likely impacts other aspects of the overall solution. The following criteria are used to assess each of the models:
- Number of tenants.
- Storage per-tenant.
- Storage in aggregate.
- Tenant isolation: Data isolation and performance (whether one tenant’s workload impacts others).
- Per-tenant cost: Database costs.
- Development complexity:
- Changes to schema.
- Changes to queries (required by the pattern).
- Operational complexity:
- Monitoring and managing performance.
- Schema management.
- Restoring a tenant.
- Disaster recovery.
- Customizability: Ease of supporting schema customizations that are either tenant-specific or tenant class-specific.
The tenancy discussion is focused on the data layer. But consider for a moment the application layer. The application layer is treated as a monolithic entity. If you divide the application into many small components, your choice of tenancy model might change. You could treat some components differently than others regarding both tenancy and the storage technology or platform used.
B. Standalone single-tenant app with single-tenant database
Application level isolation
In this model, the whole application is installed repeatedly, once for each tenant. Each instance of the app is a standalone instance, so it never interacts with any other standalone instance. Each instance of the app has only one tenant, and therefore needs only one database. The tenant has the database all to itself.
C. Multi-tenant app with database-per-tenant
This next pattern uses a multi-tenant application with many databases, all being single-tenant databases. A new database is provisioned for each new tenant. The application tier is scaled up vertically by adding more resources per node. Or the app is scaled out horizontally by adding more nodes. The scaling is based on workload, and is independent of the number or scale of the individual databases.
Customize for a tenant
Like the standalone app pattern, the use of single-tenant databases gives strong tenant isolation. In any app whose model specifies only single-tenant databases, the schema for any one given database can be customized and optimized for its tenant. This customization does not affect other tenants in the app. Perhaps a tenant might need data beyond the basic data fields that all tenants need. Further, the extra data field might need an index.
With database-per-tenant, customizing the schema for one or more individual tenants is straightforward to achieve. The application vendor must design procedures to carefully manage schema customizations at scale.
D. Multi-tenant app with multi-tenant databases
Another available pattern is to store many tenants in a multi-tenant database. The application instance can have any number of multi-tenant databases. The schema of a multi-tenant database must have one or more tenant identifier columns so that the data from any given tenant can be selectively retrieved. Further, the schema might require a few tables or columns that are used by only a subset of tenants. However, static code and reference data is stored only once and is shared by all tenants.
Tenant isolation is sacrificed
Data: A multi-tenant database necessarily sacrifices tenant isolation. The data of multiple tenants is stored together in one database. During development, ensure that queries never expose data from more than one tenant.
Processing: A multi-tenant database shares compute and storage resources across all its tenants. The database as a whole can be monitored to ensure it is performing acceptably. However, the Azure system has no built-in way to monitor or manage the use of these resources by an individual tenant. Therefore, the multi-tenant database carries an increased risk of encountering noisy neighbors, where the workload of one overactive tenant impacts the performance experience of other tenants in the same database. Additional application-level monitoring could monitor tenant-level performance.
In general, multi-tenant databases have the lowest per-tenant cost. Resource costs for a standalone database are lower than for an equivalently sized elastic pool. In addition, for scenarios where tenants need only limited storage, potentially millions of tenants could be stored in a single database. No elastic pool can contain millions of databases. However, a solution containing 1000 databases per pool, with 1000 pools, could reach the scale of millions at the risk of becoming unwieldy to manage.
Two variations of a multi-tenant database model are discussed in what follows, with the sharded multi-tenant model being the most flexible and scalable.
E. Multi-tenant app with a single multi-tenant database
The simplest multi-tenant database pattern uses a single standalone database to host data for all tenants. As more tenants are added, the database is scaled up with more storage and compute resources. This scale up might be all that is needed, although there is always an ultimate scale limit. However, long before that limit is reached the database becomes unwieldy to manage.
Management operations that are focused on individual tenants are more complex to implement in a multi-tenant database. And at scale these operations might become unacceptably slow. One example is a point-in-time restore of the data for just one tenant.
F. Multi-tenant app with sharded multi-tenant databases
Most SaaS applications access the data of only one tenant at a time. This access pattern allows tenant data to be distributed across multiple databases or shards, where all the data for any one tenant is contained in one shard. Combined with a multi-tenant database pattern, a sharded model allows almost limitless scale.
Sharding adds complexity both to the design and operational management. A catalog is required in which to maintain the mapping between tenants and databases. In addition, management procedures are required to manage the shards and the tenant population. For example, procedures must be designed to add and remove shards, and to move tenant data between shards. One way to scale is to by adding a new shard and populating it with new tenants. At other times you might split a densely populated shard into two less-densely populated shards. After several tenants have been moved or discontinued, you might merge sparsely populated shards together. The merge would result in more cost-efficient resource utilization. Tenants might also be moved between shards to balance workloads.
Smaller databases more easily managed
By distributing tenants across multiple databases, the sharded multi-tenant solution results in smaller databases that are more easily managed. For example, restoring a specific tenant to a prior point in time now involves restoring a single smaller database from a backup, rather than a larger database that contains all tenants. The database size, and number of tenants per database, can be chosen to balance the workload and the management efforts.
Tenant identifier in the schema
Depending on the sharding approach used, additional constraints may be imposed on the database schema. The SQL Database split/merge application requires that the schema includes the sharding key, which typically is the tenant identifier. The tenant identifier is the leading element in the primary key of all sharded tables. The tenant identifier enables the split/merge application to quickly locate and move data associated with a specific tenant.
G. Hybrid sharded multi-tenant database model
In the hybrid model, all databases have the tenant identifier in their schema. The databases are all capable of storing more than one tenant, and the databases can be sharded. So in the schema sense, they are all multi-tenant databases. Yet in practice some of these databases contain only one tenant. Regardless, the quantity of tenants stored in a given database has no effect on the database schema.
H. Tenancy models compared
The following table summarizes the differences between the main tenancy models.
|Measurement||Standalone app||Database-per-tenant||Sharded multi-tenant|
|Tenant isolation||Very high||High||Low; except for any singleton tenant (that is alone in an MT db).|
|Database cost per tenant||High; is sized for peaks.||Low; pools used.||Lowest, for small tenants in MT DBs.|
|Performance monitoring and management||Per-tenant only||Aggregate + per-tenant||Aggregate; although is per-tenant only for singletons.|
|Development complexity||Low||Low||Medium; due to sharding.|
|Operational complexity||Low-High. Individually simple, complex at scale.||Low-Medium. Patterns address complexity at scale.||Low-High. Individual tenant management is complex.|
Ruby on Rails Multi-tenant References
Azure Web App Multi-tenant References
Multi-Tenant Architecture Comparison Research Paper
Abstract. Software architects struggle to choose an adequate architectural style for multi-tenant software systems. Bad choices result in poor performance, low scalability, limited flexibility, and obstruct software evolution.
We present a comparison of 12 Multi-Tenant Architecture (MTA) patterns that supports architects in choosing the most suitable architectural pattern, using 17 assessment criteria. Both patterns and criteria were evaluated by domain experts. Five architecture assessment rules of thumb are presented in the paper, aimed at making fast and efficient
design decisions. The comparison provides architects with an effective method for selecting the applicable multi-tenant architecture pattern, saving them effort, time, and mitigating the effects of making wrong
Keywords: multi-tenancy; architecture patterns; quality attributes;
Traditional multi-user applications are designed to provide the same functional and non-functional responses to all the users. However, customers of the contemporary applications may have different expectations from the application. To design an application with the ability to meet diverse requirements of customers, is a recurring problem in various domains including software applications. This paper presents a pattern called “Multi-tenant” that can be employed to cater such diverse set of requirements. We present a reference architecture of the pattern along with examples and known uses. Our analysis of the various use cases shows that the pattern is useful in designing applications for heterogeneous consumers.
Categories and Subject Descriptors: D.2.11 [Software Engineering]: Software Architectures—(Design) Patterns
General Terms: Design
Additional Key Words and Phrases: Multi-tenant, Reference Architecture, Cloud Computing