Member-only story
The trade-offs between performance, cost, and security with Firestore

You’ve probably heard the old quip about project management: “Fast, good, cheap: pick any two”. The understood relationship between these attributes is that you have to sacrifice a desirable trait to do well with the other two, and getting all three is impossible.
It’s not a whole lot different when modeling data in Firestore, except the primary attributes are:
- Cost: What you are paying to get your requirements met.
- Security: Ensuring that only authorized people can work with certain data.
- Performance: All necessary data gets populated in your app’s UI as fast as possible.
For many applications, optimizing for any one of these can cause problems with the other two. Why is that? Let’s use a straightforward example.
Today you are a game developer!
Imagine you’re building a game and you need to store information about all the players. Data about each player includes:
- UID (public, assigned from Firebase Authentication)
- Screen name (string, public, very short)
- Bio (string, public, potentially very long)
- Current score (integer, public, constantly updating as they play, used with public realtime leaderboard)
- Credits (integer, private, amount of in-game credits purchased)
Of course, there could be much more to store per user, but let’s just start with this. The most straightforward way to model this data is using per-player documents in a single collection, like this:
Functionally, this works OK — all the data is there, and it should get the job done. But there are a couple of problems with this model:
- If all the fields are in a single document, you have a security problem. Anyone can get the private data, even if the UI doesn’t display it.
- If your realtime leaderboard is constantly churning with new high score updates, the bandwidth consumed is way…