Multitenancy is one of the Software As A Service –SAAS- concerns and although the concept is clearly defined there are many questions and gaps about how to design end to end multitenant software, so here there are some reviews and insights about approaches and implementations.

A common first step is starting from the ground in the data layer to separate the records by using a key (usually the TenantId). Our friends in the Java EE side use some well-known tools like Hibernate’s filters and Eclipse’s discriminators columns for this task. Many people think like7.Tenant encapsulation and framework level connection string management such that your developers do not have to worry about tenant IDs while writing queries”.

I disagree with that because the stand alone task of placing a where clause in all the queries is not a good reason to use a framework; a good design should abstract and encapsulate it. By other hand those frameworks are supposed to make implementations easier and still scalable enough but most of them create one database per tenant “dynamically”. Bear in mind that if you use different databases per tenants you’re not using the full potential of sharing resources in the economy of scale. A sample PostgreSQL implementation of such “dynamc” database creation is as follows:

// [tenant,schema] to [DataSource] mapping
private final Map<String, DataSource> schemaToDataSource = new HashMap<String, DataSource>();

* @return DataSource for current tenant+schema
protected DataSource determineTargetDataSource() {
// lookupKey represent current tenant and schema
String lookupKey = currentLookupKey();
DataSource dataSource = schemaToDataSource.get(lookupKey);
if (dataSource == null) {
dataSource = createDataSourceForTenantAndSchema();
schemaToDataSource.put(lookupKey, dataSource);
return dataSource;

I think this approach is quite terrible due to these facts:

  • The data base layer is in charge of creating its own context, so the data base layer does not have a single purpose.
  • The data base is created dynamically, so the first unlucky user of a recent created tenant will experience a delayed response because the database will be created, it’s also probably that if another user hits the same code at the same time another database will be created. This creational and concurrent complexity is unnecessary, likewise the initial parameters.
  • One database per tenant is a good approach if you work for small customers because a big one won’t scale out inside this model. Always it’s possible to add some code to make it work but the layer will be in charge of mapping tenants to databases and databases to partitions or replicas as well, which is more unnecessary complexity.

Anytime you see implementations with context support, be aware that cloud applications should be stateless; hence the following implementation is completely stateful.

Filter filter = session.enableFilter("tenantFilter");

In the .Net corner there are over engineered solutions (using top level IoC containers) an Linq based solutions. Those Linq based solutions look simple at first but make you have the TenantId spread all around your Models and break the encapsulation. The following code shows a sample of it.

public class MultiTenantAccess where T : IMultitenant
    private IDbSet set;

    public IQueryable GetQuery(int tenantID)
        return set.Where(e => e.TenantID == tenantID);

A good SAAS Multitenant data layer design should:

  • Encapsulate the TenantId management (don’t spreading it all around).
  • Be stateless.
  • Keep all tenant records in a single data store and partitioning them by a relevant key.
  • Allow further growing in key areas like:
    • Tenant aggregations.
    • Tenantless/admin operations.
  • Have a single entry point of communications with upper layers.
  • Be simple.

Finally if the architecture and design are described with buzz words like “isolated tenancy, mega-tenancy or hybrid tenancy” maybe it’s not multitenant at all.


Javier Andrés Cáceres Alvis

Microsoft Most Valuable Professional – MVP
Intel Black Belt Software Developer