4 ms·
Indeed, but if you are making a B2B enterprise/SMB SaaS, I think you are most likely to regret the opposite choice [1][2]. A lot of companies run a single insta
by gomox 6y ago
Indeed, but if you are making a B2B enterprise/SMB SaaS, I think you are most likely to regret the opposite choice [1][2]. A lot of companies run a single instance, multitenant application and have to develop custom sharding functionality down the road when they realize the inevitable: that most joins and caches are only needed on strict subsets of the data that are tenant specific.
If you get successful enough in this type of application space, you reach a mature state in which you need to be able to:
* Run large dedicated instances for your largest customers, because either their performance or security requirements mandate it.
* Share resources among a large number of smaller customers, for efficiency and fault tolerance reasons.
You can get there in two ways:
* You start with a massive multi tenant application, and you figure out a way to shard it and separate in pieces later.
* You start with multiple small applications, and you develop the ability to orchestrate the group, and scale the largest of them.
I would argue the latter is more flexible and cost efficient, and requires less technical prowess.
[1] https://news.ycombinator.com/item?id=23307172 https://news.ycombinator.com/item?id=23307172
[2] https://news.ycombinator.com/item?id=23307139 https://news.ycombinator.com/item?id=23307139
- cornishpixels 6y agoYou can always take a multi-tenant system and convert it into a single-tenant system a lot more easily. First and foremost, you can simply run the full multi-tenant system with only a single tenant, which if nothing else enables progressive development (you can slowly remove those now-unnecessary WHERE clauses, etc).
- gomox 6y agoTrue, but: In my experience by the time you reach this point you have a lot of operational complexity because you and your team are used to your production cluster being a single behemoth, so chances are it's not easy to stand up a new one or the overhead for doing so is massive (i.e. your production system grew very complex because there is rarely if ever a need to stand up a new one). Additionally, a multi tenant behemoth might be full of assumptions that it's the only system in town therefore making it hard to run a separate instance (i.e. uniqueness constraints on names, IDs, etc).
- egamirorrim 6y agoSome of the issues I see in one of my projects is high interactivity between accounts. E.g. if account 1 'sends' something to account 2 both of the shared/separate db instances need to be up or there'll need to be some kind of queueing mechanism. That's hard enough and then add to it that most clients want to BYOK to those instances
- gomox 6y agoHigh interactivity between accounts is a good reason to not adopt the proposed multi-single-tenant architecture. The scenarios discussed are B2B enterprisey apps in which the environments are essentially independent from each other.
- krainboltgreene 6y ago> You can always take a multi-tenant system and convert it into a single-tenant system a lot more easily. This is not true if your primary keys are int or bigint. It's also not true if you have any sort of unique indexes that are scoped to a table.
- ehsanu1 6y agoI think you are talking about problems going from multiple single-tenant systems to a single multi-tenant system. You parent is talking about the opposite.
- gomox 6y agoNo. For example, HubSpot runs a multitenant system. URLs look like: https://app.hubspot.com/section/$ACCOUNT_ID/etc/etc https://app.hubspot.com/section/$ACCOUNT_ID/etc/etc In the simple, YAGNI implementation of this, when you create a new HubSpot account, most likely that will insert a new row into the accounts table, and the auto generated ID of that row will be your account ID. Therefore you need uniqueness to be enforced at that level. If you want to start running a separate copy of the system, you need to refactor the system to move that sequence out of the database so that two different customers running on different clusters don't end up with the same account ID. This is just an example, but there are many problems like this that are caused by the assumption that the production system is a single unique system.
- mrunkel 6y agoThere are many ways to solve this that don't require uniqueness across all systems. https://${customer}.hubspot.com/.. https://${customer}.hubspot.com/... https://app.hubspot.com/${customer}/.. https://app.hubspot.com/${customer}/... You'd do this at the proxy/forwarder level.
- gomox 6y agoEverything has a solution, but want to bet that at least 20 different internal systems at HubSpot assume that the account ID in that URL is globally unique?
- sky_rw 6y agoYeah, it's far from a black and white issue. I am by no means against single tenant database structures, and for our initial use case it was likely the correct decision. I have not run into anything that stopped us in our tracks. My pushback focuses on two things: 1: The Rails implementation of this, specifically with off the shelf gems and integration with ActiveRecord. Presents a lot of unknown framework complexity down the road. We are currently running on a fork of the Apartment gem as it breaks under newer versions of Rails. 2: Long term support for evolving business case. Now, this is very much a problem unique to our company and how our business/product has evolved. We started out with a very clear separation of account concerns, and as we've grown and pivoted things have changed. You are unlikely to experience the same evolution we have. HOWEVER, all startups face these unknowns, and giving yourself as much flexibility early in the game will pay off down the road. There are no right answers here, you just have to think it through and weigh the costs/benefits. Maybe for you that flexibility is found in single tenant. For us it appears in hindsight that multi-tenant would have been the best long term choice.