Multi-tenant Architecture, What it really is?
In Multi-tenant Architecture a single instance of a software application serves multiple customers.
Each customer is called a tenant.
Tenants may be given the ability to customize some parts of the application, such as;
- Theme, colors, options of the user interface (UI)
- Business rules
- Conditional rendering to any component / module
- But they cannot customize the application’s code
In a multi-tenant architecture, multiple instances of an application operate in a shared environment. This architecture is able to work because each tenant is integrated physically, but logically separated; meaning that a single instance of the software will run on one server and then serve multiple tenants.
In this way, a software application in a multi-tenant architecture can share a dedicated instance of configurations, data, user management, and other properties.
Multi-tenant Approaches
There are three approaches for building a multi-tenant application:
- Database per tenant
Each tenant has its database. - Shared database, separate schema
All tenants are using the same database, but each tenant has own schema. - Shared database, shared schema
All tenants are using the same schema. Each table in the database has a discriminator column called tenant_id.
This is specifying the owner of the data.
Do you really need a Multi-tenant architecture?
Multi-tenant is not applicable for every client, it is crucial to realize the situation at hand. Usually, the multi-tenant approach makes sense for larger organizations that aim to release highly customizable apps for dozens of clients simultaneously.
If the end goal of the project at hand is to have a solution that will work within some predefined boundaries but could be customizable & applicable to customers of different nature… Then probably multi-tenant is the way to go.
If the interface of the end-user applications can be identical for different customers, then better off with single-tenant applications.
Some Pros and Cons of multi-tenant.
PROS –
- It is less expensive when compared to other tenant hosting architectures.
- An offering of pay-for-what-you-need pricing models.
- Tenants don’t have to worry about updates since they are pushed out by the hosting provider.
- Tenants don’t have to worry about the hardware their data is being hosted on.
- Providers only have to monitor and administer a single system.
- The architecture is easily scalable.
CONS –
- Multi-tenant apps tend to be less flexible than apps in other tenant architectures, such as single-tenancy.
- Multi-tenancy is, in general, more complex than single-tenancy.
- Multi-tenant apps need stricter authentication and access controls for security.
- Tenants have to worry about noisy neighbors, meaning someone else on the same CPU that consumes a lot of cycles, which may slow response time.
- Downtime may also be an issue depending on the provider.
Things to keep in mind when initiating Multi-tenant Architecture
Here’s a checklist to have at your fingertips when thinking about designing your multitenant architecture.
- A config file that contains theme, structure, and rules of individual tenants
- Global or general services that contain generic logic which is same across tenants
- Translations (not just different languages, same verse can be different for 2 clients)
- Separate environments for each tenant (dev, staging, prod)
- Separate commands for running/building app for different environments
Examples of what is not following multi-tenant…
And the reason behind it.
The majority of the social platforms that we use every day (i.e; Facebook, WhatsApp, Instagram) are not multi-tenant, rather single-tenant, as they are made with keeping only the end-user in mind and they function the same way for almost all users. They do have separate areas for advertisers, developers but that is simple ACL, nothing multi-tenant going on there.
Usually, Apps that are designed to function effortlessly for larger crowds are not multi-tenant. They are solely focused on the target audience and target demographics. On the other hand, multi-tenant applications are more focused on having a similar approach for multiple clients’ needs.
Which is the best tech stack for multi-tenant?
Multi-tenant could be achieved with any modern stack given the time effort. But some tech-stack focus
more on this domain and can be relied upon for the long run as previously successful multi-tenant architectures are built on them.
In the javascript realm, the following are good go-to options…
- MEAN
- MERN
- MEVN
Do micro-service and multi-tenant go together?
As many of you would ask these questions…
Can micro-service architecture facilitate multi-tenant?
If so, then is multi-tenant really different?
Can they both co-exist and overlap?
The answer to all the previous questions is Yes!
Micro-service is an architecture in which if needed multi-tenant can be incorporated. The same goes for multi-tenant, read it again replacing both words.
In the traditional microservices architecture, smaller services/modules are made which work independently. Meaning a microservices-based app can be composed of only 2 services or 200+ services… Totally depends upon how you need and bundle them.
The multitenant part is how those 2 or 200+ services are shown to the end-user. The UI, look and feel along with some additional logic can make truly different variants of that simple 2 services-based application.
Explanation
Fig A, is a microservice in action with a single tenant.
Fig B, is a micro-service with multi-tenant.
The look and feel are changed for 2 tenants but the overall functionality of service 1 and Service 2 will
remain the same. Along with the look and feel, some more helping options can be added for each tenant. But
those options will be copied to both tenants, only conditionally avoided in one tenant were not needed.
Hence, keeping things simple… Both of them go hand in hand.
Server-side of Multi-tenant.
The Server-side of multi-tenant keeps an ACL and treats each tenant as a user. The server-side is hit with
a tenant-specific key, which in return fetches the data for that tenant/user.
Hence, one DB can be used for a multi-tenant approach if needed. Obviously, better to have isolation of
concern and separate databases for each tenant. But if in the starting period of most multi-tenant apps
single database is referred to.
The logic on the server is definite and the same for all the tenants, meaning each tenant has the possibility to
grab and show features of other tenants. But each tenant usually fetches only what is required for them.
So most of the conditional work is actually handled on the front-end of applications.
Structuring the front-end of multi-tenant
It is important to realize that the skeleton of the application would be the same for all tenants. Most, if not all things/components would be general and can be used by any tenant. Keeping the tenant-specific logic in separate folders is good, having them as separate small applications are better. This way you can truly control the ability to fetch, render and avoid any module at the application level.
Keeping the on-demand artifacts lightweight and fetching larger ones such as images, banners, heavy sections.
Keeping translations in separate files, and tenant-specific translations in their config.
Better to have Debug and Translation modes (they help a lot!).
Highly customizable components are the target!
So, by seeing the overview you can visualize smaller components for almost everything.
But how to make them truly customizable?
The answer: binding conditional styles and classes.
Hiding classes or whole sections if conditions are not met, and listening to events to fire these changes.
The end goal is to have highly customizable components which fit every tenant. Along with each new
tenant, new stuff might be added to the existing components but it will be hidden for legacy customers,
unless they opt for a newer version of your application.
Binding the styles, local & remote / API fetched.
The best thing would be to have remote/API fetched styles as then they can be controlled through a dashboard. But
if that is not viable, no worries. You still have the tenant-specific folder or the smaller application. In there
you can easily make root level styles, and hitting them either with deep-dom changes or important tags,
higher z-index if feasible.
In most cases, the API-fetched styles take a bit longer. In this scenario, it is best to have fallen upon styles on
the root level. Hence, when fetching the styles or if a user is not able to fetch them for some reason, there will
still be your barebone styles taking care of things.
Hint: this is also a good place to have preloaders.
Keeping the Expectations Real.
In the end, it is important to keep your expectations real. The multi-tenant architecture is a way to produce different variants of a similar thing, on the very basic level it is the same thing disguised as different copies.
You should not expect a multi-tenant app to have different core logic for each tenant. You can have variants of logic listed, and each tenant can pick from that list. Each tenant has the possibility to switch to another logic at any time.
The thing to remember here is that you are only choosing for one tenant, and creating for all.