Better to Read Once, Write Many or Write Once, Read Many?

180 views
Skip to first unread message

Brad Dwyer

unread,
Aug 14, 2013, 12:19:04 PM8/14/13
to fireba...@googlegroups.com
I'm working to add a leaderboard of your friends's scores into a game. I have two thoughts on how to do this structure but I'm not sure which would be best or most efficient in Firebase.

The first option would be to score each user's high score in one place and have all of their friends subscribe to that node to listen for updates. It would look something like this:

Listen to your friends' scores:
$.each(CurrentUser.friends, function(friend) {
new Firebase(some_base_url + friend).on('value', updateLeaderboardWithUserSnapshot);
});

Write your new high score:
new Firebase(some_base_url + me).set(newValue);

The other option would be to write the score to each of your friends' leaderboard when you save it and just have them be listening to one leaderboard that represents all of their friends. Something like this:

Listen to your friends' score:
new Firebase(some_base_url + me).on('child_changed', updateLeaderboardwithUserSnapshot);

Write your new high score:
$.each(CurrentUser.friends, function(friend) {
new Firebase(some_base_url + friend + '/' + me).set(newValue);
});

So the question is -- is it better to store data in one place and have clients listen to many (potentially hundreds) nodes for changes or to write data into many (potentially hundreds) nodes and then just be listening to a single node for updates?

What are the tradeoffs to consider here?

Andrew Lee

unread,
Aug 14, 2013, 12:35:21 PM8/14/13
to fireba...@googlegroups.com
Hi Brad -

Good question!

The best approach here will depend on the number of friends' high scores you want to display for each user. Subscribing to a new piece of data has a bit of network overhead, so if you're subscribing to large numbers of individual locations, you may see some slowness on page load. Conversely, writing to large number of locations can be slow as well. 

If you have an asymmetric follower graph, I'd recommend choosing the method that has the lowest max number of reads / writes (so if users follow lots of people, I'd do the denormalize-on-write approach, whereas if users are generally followed by lots of people, I'd do the denormalize-on-read pattern).

If this is a symmetric friend graph, that's probably a wash, so I'd consider what happens more often: a page load, or a new score being recorded? That would help you pick the highest performing solution.

All of that said, if the numbers are smallish (low hundreds of friends or less), performance will probably be fine, so I'd just do whatever is simplest from a code perspective. In my experience, the denormalize-on-read approach is a lot simpler to implement as it keeps your data normalized in Firebase. So I'd start there.

-Andrew 


--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Andrew Lee
Founder, Firebase
http://twitter.com/startupandrew

Brad Dwyer

unread,
Aug 14, 2013, 9:59:26 PM8/14/13
to fireba...@googlegroups.com
Thanks Andrew. Trying to work this out. I think I'm leaning towards the write many solution since I'm only going to want to pull the top 3 of your friends to display and that way I don't have to potentially pull several hundred and sort them (or listen to changes when someone low down on the list gets a high score).

Is it just the initial subscribing that has overhead or does each subscription take up resources on an ongoing basis until it's removed? Is creating a thousand .on('value') listeners for 'parent/1', 'parent/2', 'parent/3'... significantly more resource intensive than creating one .on('child_changed') listener for 'parent' (if parent has 1000 children)?

Also, a related question: how much more resource does a .on('value') call take up than a .once('value') call on the same node?

- Brad

Andrew Lee

unread,
Aug 14, 2013, 10:13:54 PM8/14/13
to fireba...@googlegroups.com
Hi Brad -

Ahh -- that makes sense. If you need to sort them, denormalizing on write is probably the way to go. 

It's just the initial subscription that takes overhead -- because we have to send that info down to the server. It's not alot of overhead, mind you, but if you do hundreds or thousands of listens, it could add up. If you can get away with listening once at a parent without loading much extra data, I'd do it.

In general, once() is *less* efficient than on. The initial overhead is the same, but calling once() a second time means we need to pull fresh data from the server, whereas with on(), only deltas are pushed to the client. For performance, I'd stick with on() as much as possible.

-Andrew
Reply all
Reply to author
Forward
0 new messages