Understand the scaling of RealTime Database (Firebase)

Viewed 265

I have recently asked a question about sharding data in RTDB that works fine. However, the scaling to go over the Firebase limitation is still an issue.

Let's take an example :

  • User A has its user record in DB1.
  • User B has its user record in DB2.
  • User A has started a conversation in DB1 with User B.
  • User C has started a conversation in DB2 (with the shard system) with User B.

In such case we have load balanced the DBs. But we still have the problem of simultaneous connections.

That means User B should be connected in both DB right ? On another hand, the record of User A is in DB1, the record of User B in DB2. If the user A needs to see if user B is online, he also needs to connect to DB2 etc...

The conclusion so far is that the number of database instance doesn't matter to scale. It will definitely not help bypassing the 200k simultaneous connections as every user will probably be connected to every DB instance.

The only way i was thinking of is to have many real time databases that have all the same data, updated with Cloud functions... This way only, users could connect to any DB (and only 1 especially !) and be able to see the same data as another user connected to another DB.

Is it necessary to do such extreme thing ? Am i missing something that makes me say such conclusions ?

2 Answers

There are many ways to model this data, but a lot depends on the actual implementation and usage patterns. Since I doubt you already have those, we're gonna be speculating a bit here.

Some considerations and some honest expectation settings:

  • The 200K limit is for users connected to a single database instance concurrently. Nobody is chatting all the time, although we all have friends who we think chat 24/7. We used to have guidance that even on pretty active systems we saw at most 70 users for each concurrent. That number probably changed a bit over time, but the 200K concurrents typically stretches a lot further than 200K daily active users.
  • The 200K is an upper limit, but the database also has a load factor: the amount of traffic it can process. Many database instances will hit their maximum load before they hit their maximum number of concurrents. There is no precise calculation for this load, but the Firebase console shows it for each of your databases, so you can keep an eye out there as you're performing your first performance tests. You can also write this information to Cloud Logging, for a more persistent view that you can also then code against. For more on this, see the documentation on monitoring database performance
  • You'll typically want to look out for how the load increases as you add users. The main shapes to look for: is it linear, sub-linear, or exponential? Once you know that, you'll have a pretty important factor in determining how many users you can actually support on a single database instance. The CLI tool for monitoring performance is typically a great aid in this phase too.
  • Next you'll have to think of how you're going to determine the number of shards you need, and how you're going to distribute the users over those shards. I highly recommend reading scaling with Multiple Databases in the documentation. Chat systems are typically fairly easy to shard, as each chat room/conversation is isolated in nature.
  • A chat system where you have >200K users that all can be talking to all other users at the same time, has 200K^2 possible combinations, so over 40 billion possible chat conversations. Now I know we all love to chat, but even if we're very optimistic - we're gonna end up with a very sparsely population in this possible address space. This should influence your data model, for example: how do you allocate the conversations over your shards? We can't ensure that all conversations from a single user are in a single database instance (after all, every could talk to every else), but can we somehow cluster them?
  • A single client can connect to multiple database instances, and that's actually pretty cheaply. So we might be fine with a relatively minor clustering or no clustering at all. We'd need a way to lookup the mapping from a user to their chat conversations, and from each conversation to the server they're allocated to, but that information is fairly static once written. Which brings me to...
  • The user data is typically a lot more static than the chat messages themselves, a split you see in many scenarios. You can duplicate the more static data to each database instance pretty easily, but you could also consider performing a static lookup for the REST API for it when needed. These days I'd also consider using Firestore for the more static, larger user profiles, and then use RTDB for the more dynamic chat messages themselves.

The list above is far from complete, but merely some of the first thing that comes to mind. So consider these some initial considerations when designing the data model for a large application. You should treat this as a process, and not as a question that can be answered succinctly.

Oh, and you should probably also read the documentation on optimizing database performance, which likely explains a lot of the above much better than I did. :)

Realtime db would have issues scaling with the model you put forward. Granted 200k users are a lot of concurrent and active sessions, as real-time instances use socket-like listeners within real-time DB.

The 200k limit is by no means a hard limit cap, as it was enhanced from 100k semi-recently and firebase offers the option of discussing and arranging more connections should your app need it.

With that being said, a connection is when the client module creates an active listener for the client's session. This means that if you initiate the connection to multiple DB's with the client, it will consume a connection for each database.

A workaround to this is to use the Rest API to make a general get request to read data, the issue I see is how do you know if user A vs user B on different database instances.

Ultimately, options are available to increase limits, and the correct data model can improve some of these issues.

Related