A web application we wrote intended for one customer is going to be product-ized and sold to dozens of companies, and we will be doing the hosting.
I could use some guidance about the pros and cons of rolling out a seperate instance for each customer versus going with a single (or very small number of) multi-tenant instances.
At first, as we ramp up, I will have to roll out a seperate instance of the application for each new customer (they will come online one at a time) because it’s the only immediate option. I imagine this won’t scale very well as far as maintenance goes – rolling out changes will become very tedious and possibly error-prone once there are more than 4 or 5 instances out there. Unless we automate that somehow.
Also, the single-instance philosophy seems like it might lead to a bunch of forks if people need customizations. And it would be nice to avoid that.
So what has your experience been with this?
Bonus question #1: What’s the performance difference between 10 SQL Servers with 2m records each versus one huge one with 20m? Let’s say they are all in one table and we’re mainly doing inserts and selects on single records. Sometimes the selects are on an indexed varchar(12) or date field.
Bonus Question #2: I imagine that to avoid forking, we would have to make the customizations configurable, or build a plug-in architecture. However, that might increase the cost of doing customizations, and I don’t want to be one of those shops that takes a week to resize a textbox, and I don’t want to over-invest in infrastructure. Any thoughts on that?
Scale Details
Each customer will have a decent amount of data — up to a few million records.
There will be a very small number of concurrent users, only a few per customer, plus a handful of internal reps on our end.
It’s unclear whether each customer will require customizations, but I would say some of them probably will, and maybe some of those changes will be things that other customers will not want to see.
I don’t see a good reason for either of your two options. I think the real answer lies somewhere in the middle: having multiple instances, each hosting multiple clients.
This adds another layer of automation processing, but it means you can keep the hosting cheap (you won’t need to go out and buy a Cray any time soon) and (hopefully) this sort of mentality means you could do failover backups fairly easily.
But let’s not get ahead of ourselves… We’re talking about a webapp, right? Get your database(s) and aspnet on different machines. Cluster your databases and you’ll have a much happier time playing around with various front-end scenarios. You’ll also be able to upscale whichever area runs out of puff first.
By the sounds of it, you’ll end up with one clustered database over half if not a full dozen database machines and only a couple of front-end boxes.
As for customisations, you’ve nailed it. You either provide a completely database-hosted set of editable templates or you have to customise who instances. I’m all for the first. It’s a lot of work (without much in return) but it’s well worth it as you should only need to change the core code when (you will!) you do upgrades. Hunting through a hundred customers’ custom instances to make sure they upgrade safely will kill a developer! Template are the answer. At the very very least, you could allow custom CSS without much pain (but they’d need somebody who knew their stuff).
Edit: I’ve seen a couple of posts going for the all-in-one method. Splitting the instances over multiple machines insulates you from a couple of things:
If you introduce a bug not caught in testing, only a few clients are effected at once
Hardware fails. Having one mega-server fall over will annoy a lot of people at once. Having a failover mega-server is massively expensive. Having a spare failover box per three or four running servers is much cheaper and annoys fewer people.
Performance can be balanced between boxes on a client-by-client basis, so you can put a few light-use clients with a heavy client, or just fill a box with a few medium-use clients, etc.
On the same idea, usage spikes or other slowdowns only effect clients on the same box. Of course this doesn’t mean the same for the database, but you can split that up into a cluster of clusters when you get there.