Live data from Hacker News

Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

news.ycombinator.com

171–180 of 264 posts

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#171
We do that where I am. I think it's been in place for about twenty years - certainly more than a decade. We're on MySQL/PHP without persistent connections. There have been many questionable architectural decisions in the codebase, but this isn't one of them. It seems quite natural that separate data should be separated and it regularly comes up as a question from potential clients.

Each client's db is a little different due to some more questionable decisions (e.g. different features can result in different databases turning on, and most tables will have variable names). But it's not really any harder to write code that says "`select identifier from features_enabled` -> derive table name -> `alter (derived table name) add column baz`" (actually, nowadays we have an inhouse database migrator that does that for us, we just say "the table abstractly known as `foo` should have columns bar, baz, quux" and the migrator says "for this client, they have the feature uses_foo enabled with the identifiers A and B, so A_foo and B_foo should both have the columns baz, but do not; I will add it after `bar`".)

Perhaps it has discouraged us from seeking to use persistent connections. But that is not the biggest inefficiency in our system at this stage.

If I was designing the application from scratch, I think I would want a static schema, but database-per-tenant seems fine.

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#172

In the past I worked at a company that managed thousands of individual MSSQL databases for individual customers due to data security concerns. Effectively what happened is the schema became locked in place since running migrations across so many databases became hard to manage. I currently work at a company where customers have similar concerns around data privacy, but we've been to continue using a single multitenan…

Also have thousands of MSSQL databases, but with significant investment in tooling it really is transparent from a feature development standpoint, and our feature toggles are dirt simple.

Another comment suggested doing queries across so many databases is challenging, and it's just not, we have both adhoc query capabilities across the fleet and a traditional data warehouse...

Now, trying to make additional infrastructure changes is challenging, but the architecture is robust enough to solve all the immediate business needs.

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#173
post #85

Disclosure: I work on Google Cloud. tl;dr: Wait until you need it, but there are good reasons for it! Since I didn’t see anyone mention it, the term I’ve seen a lot of people use for this pattern is “multi single tenant”. Part of the reason we have Tenant Projects [1] is precisely so you can do a 1:1 mapping of “Customer A can have different controls, settings, and blast radii from Customer B”. Many of our first-part…

Thanks for shraring! It’s great advice! Mind elaborate on the single replicated db approach? Curious what the replica’s role here that makes a project scale.

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#174
I would be interested to know what is driving you to consider this approach?

For example, I imagine one database per account would make it easier to provide your customers with a flexible reporting solution.

Most of the reporting solutions available do not have good support for row level security.

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#175
post #108

My startup currently does just this 'at scale', which is for us ~150 b2b customers with a total database footprint of ~500 GB. We are using Rails and the Apartment gem to do mutli-tenancy via unique databases per account with a single master database holding some top-level tables. This architecture decisions is one of my biggest regrets, and we are currently in the process of rebuilding into a single database model.…

Can confirm, here be dragons. I did a DB per tenant for a local franchise retailer and it was the worst design mistake I ever made, which of course seemed justified at the time (different tax rules, what not), but we never managed to get off it and I spent a significant amount of time working around it, building ETL sync processes to suck everything into one big DB, and so on.

Instead of a DB per tenant, or a table per tenant, just add a TenantId column on every table from day 1.

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#176
We're a small company (~50 customers) delivering SaaS using Django/Postgres/uWSGI for a niche B2B market where privacy and data confidentiality is paramount.

Currently we deploy one DB + unique uWSGI instances for each customer. This has some drawbacks which has made us look a bit into multi-tenancy as well. Everything is served on dedicated hardware, using common codebase, and each customer is served on a unique sub-domain.

The two primary drawbacks of running unique instances for each customer are ease of deployment and utilization of resources.

When a new customer is deployed we need to set up the database, run migrations, set up DNS, deploy the application, deploy the task runner, set up DNS and configure the HTTP vhost. Most of this is painfully manual right now, but we're looking into automating at least parts of the deployment.

In the future, we aim to offer an online solution for signup and onboarding, where (potential) customers can trigger the provisioning of a new instance, even for a limited demo. If we were doing multi-tenancy that would just require a new row in the database + some seed data, which would make the deployment process exceptionally simpler.

The other issue is the utilization of resources. Running a few instances of the application with a big worker pool would be much easier to scale than running 50+ instances with their own isolated worker pool.

We're considering maybe going for a hybrid multi-tenant architecture, where each customer has their own isolated DB, but with a DB router in the application. That would give us a compromise between security (isolated databases - SQL queries don't cross into another customer's data) and utilization (shared workers across customers). But this would add another level of complexity and new challenges for deployment.

Do anyone have a similar case as this?

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#177
We set off building a new product using this approach a few years ago and wrote about our motivations here: https://medium.com/hackernoon/exploring-single-tenant-archit...

I can't remember all of the reasons that we ditched the idea, but it quickly became clear that we would be writing a lot of the core tooling ourselves, and we kept running into problems with AWS around dynamically provisioning the load balancers and certs for N boxes.

I wouldn't dream of trying to manage different schemas across all the databases either, that sounds like a serious headache that could only be mitigated by having separate codebases and separate development teams managing them.

If a customer needs custom fields, I would make them a first class citizen and the required `fields_definitions / field_values` tables to your database and let them manage those fields themselves.

I'm glad we ended up defaulting to a multi-tenant architecture even though we lost some of the proposed benefits (isolation, independent scaling etc).

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#178
I considered it a few years ago for a project. My options were one db per account, one schema per account or good old fashioned multitenant. The first two options dropped after realising what a maintenance nightmare that can be. In my scenario I would have thousands and thousands of accounts. So a migration becomes a crazy notion you'll be trying to avoid. The same applies for multi schema - there is a limit of how many schemas you can run reasonably before performance is affected.

What I ended up doing is going for a multi tenant architecture, but I built it in such a way where the data is transient from one db to another. All account data lives in a separate 'master db', and the data in another. All ids are UUIDs. I build database routing into the application so each "account" can have it's data on a different database, and if needed I can move one account's data from a loaded db to a more available one.

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#179

I’ve managed a system with millions of users and tens of billions of rows, and I always dreamed of DB per user. Generally, ~1% of users were active at a given time, but a lot of resources were used for the 99% who were offline (eg, indexes in memory where 99% of the data wouldn’t be needed). Learned a few tricks. If this is the problem you're trying to solve, some tips below. Start by optimizing your indexes. Ensure…

Thanks for the insight into clustering. We do slightly similar things by using snowflake or redshift, but that's because we can afford few hundred millisecond timescales for the analytical queries. Good to know MySQL can cluster!

I have dreamed of personal projects where I'd have to handle a ton of data for an individual user (eg. Service where I'll put all the users office documents in their Dropbox under git on the cloud and give them fine-grained revision history), and the most cost effective solution I was able to imagine involved one sqlite per user, stored on something like EFS (or a very large EBS). Never took too many steps there though, mainly because it wasn't clear if the product was of any value.

Re: Ask HN: Has anybody shipped a web app at scale with 1 DB per account?

#180
post #151

Earlier quoted context omitted.

You roll the feature out incrementally to the users who are ready. You build backwards compatible features. Basic software engineering.

> You roll the feature out incrementally to the users who are ready. You build backwards compatible features. Basic software engineering. The parent mentioned having to support ~150 B2B customers, so the effort is amplified x100 — more than 100 individual customers databases have to be coddled as you’ve described, albeit they are stuck with poor tooling to manage changes across their unusual architecture.

While not a web-app, we too have ~200 B2B customers running our application and each one have their own DB. Some self-host, most others are hosted by us.

We have written our own tool to upgrade the DB schema, it's nothing fancy, just takes an XML description, compares with the current DB and makes changes. However it ensures the upgrade process is automated.

New versions of our application come with a new DB schema, and we also have an auto-updater for our software. We have a small launcher application which allows the users to select a few older versions of our software, so upgrades are almost always safe in the sense that if the user encounters a bug with the new version, they can try in the previous one.

If the DB schema upgrade tool fails for some reason, the application upgrade will be held back and we'll get a notification.

Combined this allows us to be quite aggressive with pushing out new versions, and to do so without manual intervention.

A limitation with this setup is that DB changes have to be backwards compatible. So we do have a few cases of "if this table exists do this, else do that" type logic and similar, but mostly it's not a big deal.

For example I recently had to refactor some old table where they had used five columns for some additional references (ref_1, ref_2 etc), into a new table of additional references. To handle this I just made a new view which would return either the refs from the new table, or the data from the columns in case the new table didn't have any data for that record.

I then changed the application to use a grid instead of five separate edit controls, and to use this new view. If the user had to use an older version, that version would just write to the five fields and not populate a row in the new table, and the view would then return this data if the user later viewed it in the new version of our application.

So the "overhead" of backwards compatibility in this case was just ensuring this would be sufficient and writing that view, so just a few minutes.

Post reply on HN