I am asking myself the exact same question at the moment.
I am leaning towards the multi-instance single tenancy solution but have not taken a definitive decision yet. Let me share some of my thoughts :
The main historical advantage of the multi-tenant architecture is a better use of infrastructure resources, by mutualisation (single OS, single Database, single application layer) and better occupying of said resources (when one user is away another can use the same resource).
It also greatly simplifies software lifecycle : you deploy new versions to you one instance, all the customers are updated at the same time.
It seems however, that recent advancements in cloud technology make the first class of advantages largely available in a multi-instance (instance-per-customer) architecture (I am thinking specifically of a platform like Jelastic here but I am sure there are others that provide the same features):
- Container-based PaaS
- Provisioning and auto-scaling of containers (elastic containers)
So hardware and platform management is not the Software provider's concern any more. Resources are mutualised much more efficiently than before at the infrastructure and plaform levels.
There will still be an overhead for multi-instance (some app and middleware will be ran N times instead of just one), but much lower than when using a separate (virtual) machine per instance. The database could be shared anyway (one schema per instance, several schemas per DB server)
Also :
- Automation of creation of new instances is possible via PaaS API
- Automation of deployment of new versions is possible via PaaS API, with zero downtime (takes some work to put in place)
- Scaling is always out, never up. We don't have to worry about huge datasets at the instance level.
Of course, we would need some kind of central service that manages all this automatically (e.g. creation of instance when a new user creates an account). This would also manage payment and licensing issues, interaction between instances etc. This central service might be quite complex and hard to develop, but the good thing is that we don't have to implement it upfront (now that we don't have much resource) whereas multi-tenant would need to be baked into the app from the start.
Which brings me to the final advantages of developing single-tenant for a very early stage (pre-invesment) startup project :
- Same (or almost same) version of the app can be deployed on-premises either as a virtual appliance or docker container or even on customer-managed machine (some companies are still reluctant towards the Cloud and it may help an early stage startup to not push out important early adopters)
- Faster to get a product out with limited resources (the application layer and database schema is quite less complex), can get a "dumb" single instance single tenant product out first (MVP) for early adopters and to show the business value of the app to potential investors, and add all the cloud automation later on
- Can be seen as a selling argument for customers worried about data security : the data is better encapsulated since every customer has his own schema or even database. Much less risk of "spillage"
NB: I am obviously thinking here of a business app where customers would be businesses (each with multiple individual users) and not individuals. It would not make any sense to run a separate instance of an app for each individual user (or would it ?)
Best Answer
Oof, big topic. Yes, this can be a typical pattern in enterprise-class software, but I don't necessarily think it's a good one. Consider avoiding it if you can. The core issue here is that it exists at a super-high level of abstraction. When a tool doesn't know what the user wants to do, it inevitably abdicates the decision and gives you a framework for building your own tool. This starts off as a cool sales pitch about customizability, but in some ways MDA is the ultimate scope creep; if you become that flexible, really there's nothing your software can't do (in theory).
This is such a classic mistake that there are all kinds of jokes about it.
Zawinski's Law -- "all truly useful programs experience pressure to evolve into toolkits and application platforms"
Greenspun's Tenth Rule -- and others too.
Bottom line for me, MDA exists at a very high level of abstraction. Systems should avoid over-abstraction. I think it's too much to say categorically that you should never do this, sometimes it might work, but you better have a damn airtight case why it's necessary before you do it, otherwise I'd argue it's over-abstraction.
Specific engineering design patterns - really it's about creating database entities and relationships in a very abstract way, and allowing the user with a UI to specify and relate those things. On the UI side, same concept except instead of using database entities/relationships, you're using panels, inputs, forms, etc.
Open source alternatives - not sure on this one, but I would be wary of them if there are, because usually "super flexible" solutions end up getting customized to the problem domain (CRM, or whatever). Maybe some of the interface and data builders that come with Eclipse?
The issues that come with these approaches are many.
Testing the Beast
Because it's so abstract, testing becomes very hard. It's not possible to test every combination, so designing a representative covering suite is a very hard thing to do. That new feature you developed, does it interact poorly with Customer X's bizarre customization that was really working against how the tool was supposed to function in the first place?
Understanding Your Own System
Second, it allows the user to encode knowledge into the system that the system itself doesn't have. Imagine a back-end engineer looking at a customization of his own system and having a hard time recognizing where to start, because knowing your way around depends on knowledge outside of the system's specs. An earlier commenter pointed out that for salesforce, you have to hire special consultants to help you implement it. Yep, sounds right.
Inappropriate User Expectations
There's a general tradeoff between system power and simplicity; these systems are very powerful, and tend to be the opposite of simple. So basically all of the downsides of complexity come in the bargain for more flexibility. This also creates in the users and product managers a sense of "we can do anything" which makes it very difficult to set and understand proper system scope boundaries.