Multitenancy - App

If all the tenants have the same system behavior, we can just use webfarm with one single web application instance. But we allow tenant to customize the behavior of the system. It brings a lot of complexity.


In multi-tenancy application, the system components will be looked like this:


We have different combination of physical components (DLLs) for each tenant. That means we have to host each tenant as each web application in IIS, otherwise we have to load all the customize component (DLL) into the single application domain. One web application per tenant setting also has some trade-offs that we need to consider.

  • Isolation: Since each tenant is one app instance, they won’t effect each other.
  • Debugging: Each tenant has its own worker process. It is much easier to debug single tenant context.
  • Resources monitoring and management: Resource usage is separate from each tenant. It is much easier to monitor and manage tenant’s resource usage.
  • Deployment: It is the main drawback of this approach. It is more complex than single instance webfarm when we need to deploy. When we upgrade the Core system component, we have to deploy all the web application instances of all tenants.


Basically, we need to have some extension point in the core system. We can achieve that by using strategy patterns and the likes. The most common mistake is trying to make very flexible system at early stage. My advice is try to keep it simple and focus on Single Responsibility principle at first and apply strategy pattern when needed. (I am not saying that strategy pattern is the only way for extensibility. You may also want to use MEF. So, it depends.)

Multitenancy - Data

When dealing with data in multi-tenancy application, we have to think about physical storage and extensibility.

Physical storage

Regarding storing data in RDBMS, especially in SQL Server, we have a few options.

  1. Shared database instance, i.e. add tenantId to all the the tables related to tenants and query by tenantId and other filters.
  2. Multiple database instances, i.e. create each database for each tenant.

The first option looks simpler compare to the second one, but if we think about security, isolation, backup and horizontal scaling, it brings more challenges.

  • Security - I believe multiple db instances option is much more simple than shared database option when it comes to security.
  • Isolation - Obviously, the multiple db instances is better.
  • Backup - It is also much easier to work with multiple instances to backup, extract data and give it to your tanent when it is requested. And the cost is also much more predictable since it is just related to numbers of tenants you have.
  • Scaling - I think, this is the major issue of shared database instance. The option to scale horizontally in Sql Server is through partitioning. It is way more complex than putting multiple db instances on multiple servers. And it also have flexibility to make more pricing options such as dedicated db server for one tenant.
  • Release Management - This is one advantage of shared database instance. It is much easier to add one more record in database than creating new database, setting up security option, etc. Of curse, we still can automate this but it is more complex than shared db instance.


When tenants want to customize behaviour of the system, they usually require some custom data to work with. We also have some patterns to work with custom data:

  • Preallocated Fields - such as Field1, Field2, Field3, etc.It will usually lead to maintenace nightmare because the developer have no idea what is the usage of Field1. Field1 can also be different usages for different tenants.
  • Name-Value Pairs - with one value table (TenantId, ExtId, Value) and one meta table (TenantId, ExtId, ValueDesc, ValueDataType). The main dis-advantage is query. It is very complicated to make efficient query with those kind of tables. The performance is usually the issue when data grow.
  • Custom Columns - directly add more columns to existing table. It is the simplest solution to data extensibility. The only drawback is conflicts between customer-defined-column and newly-added-column. It can happen when we want to add new column in next version but customer alread use that column. E.g. After we release v1, tenant A add “Location” column to customer table. When we want to add “Location” column in v2, we have conflict with tenant A.
  • xxxxx_Extented - add one-to-one relationship extended table to existing table. By doing this, we still have simplicity to work with custom data since we just need a single join, as well as solving the versioning issue. E.g. Cusomter table and Customer_Extended table with additional tenant-added-columns.

In next post, I’ll talk about application, especially web app.


Multitenancy is defined in wiki as:

Multitenancy refers to a principle in software architecture where a single instance of the software runs on a server, serving multiple client-organizations (tenants). Multitenancy contrasts with multi-instance architectures where separate software instances (or hardware systems) operate on behalf of different client organizations. With a multitenant architecture, a software application is designed to virtually partition its data and configuration, and each client organization works with a customized virtual application.

In the cloud computing, it is SaaS (Software as a Service) with some customizations. In this kind of application, the complexity is customization. If it only allows to customize skinning and allow to add some additional fields, it mostly works like normal single-tenant application. But if it allows to customize behavior of the applications, it is different story.

In this blog post, multi-tenant application means it allows tenant to change not only skinning but also some behavior of the application.

Lets say, we are building multi-tenant E-commerce web-base application. At very high level, we have a few tenants with some customization to our core web E-commerce application and one tenants management application in our hosting.

Lets see what are the requirements for our multi-tenant application.

  • Isolation - each tenant should isolated from each other, including data and system uptime.
  • Sacability - our hosting should allow to scale horizontally because we can’t just host all the tenants in one server.
  • Extensibility - each tenant should allow to customize some behavior of the core system.
  • Release Management - we should able to release updates/hot-fixes to each tenant without affecting other tenants. But if we do updates/hot-fixes to the Core system, we should be able to release all the tenants as well.
  • Single source code - there should be only one source code for the Core system. It requires to mention specifically because I want to highlight that we are not building copy-paste-customize system. (sound familiar?)
  • Simplicity - Actually, it applies to all the systems. When building customizable system, the simplicity is much more important because people tend to build the system which allows to customize dynamically. Dynamic will lead to a lot of complexity.

In the next few posts, I’ll talk about how are we going to build multi-tenant application.

Productivity in software development

As we all know, productivity doesn’t increase just by working more hours. In fact, it has negative effect after you exceed your limit.

Productivity vs Working horus

So, how should we move from red to green? Simple. We need to get more things done in less working hours. But it is not easy to do. Thinking about productivity remind me about the great talk by Scott Hanselman. I watch it again. If you haven’t watched yet, do it now. This time, I aslo took some notes as if I’m in the lecture room.

  • Effectiveness and Efficiency. Effectiveness is doing the right things. Efficiency is doing things right. We need to do both to improve our productivity.
  • Too much information. There are just too much information in the internet age. We are wasting so much time on twitter, facebook, news, etc. We have to ignore most of those.
  • Overtime. When we think we need to work overtime to catch up deadline/scrum goal, it is the danger sign. Avoid it. It may be either we have many things to do or we are not doing things right.
  • Email rule. CC means FYI. Put all CC mails in one folder and read it all in scheduled time.
  • Checking email. Don’t check email in the morning. We are using scrum, we should know what to do at our morning stand-up meeting. Schedule to check your mail, e.g. check email after lunch.
  • Pomodoro. If you don’t know, go and read about it. And use it. I usually target to achieve 4-6 pomodori. Yes. There is max limit for me.
  • Chrome tabs. Many chrome tabs usually means we are wasting memory and overloaded with too many information. Close what you don’t need.

Installing jekyll on Windows 7

I’m using github pages for this blog. Today I’m setting up jekyll on my new laptop which is running on Windows 7.

While setting up, I noted down the steps for installing jekyll on Windows. Hopefully it can help someone like me who want to use jekyll as blogging system and also need to use Windows.

Here are the steps;

  1. install Ruby
  2. download Ruby Dev Kit which is required to build native gem and extract it to path such as C:\RubyDevKit. And then run the following commands ruby dk.rb init and ruby dk.rb install. ruby and dev kit
  3. install jekyll gem, gem install jekyll jekyll gem
  4. install rdiscount gem, gem install rdiscount. (I can’t manage to work maruku in my machine. Since rdiscount is faster and working fine on Windows, I just use it.)
  5. install python (this steps and belows are required for pygments syntax highlighting.)
  6. To install easy_install download from here and run this command in python, python.exe
  7. install pygments using easy_install; easy_install.exe pygments install pygments
  8. you might need to add Pygmentize.exe in your PATH. In my case, it is C:\Python32\Scripts.
  9. if you got error like Liquid error: Bad file descriptor when you running Pygmentize, you need to change this file C:\Ruby192\lib\ruby\gems\1.9.1\gems\albino-1.3.3\lib\albino.rb as this gist.