Design Question with focus on performance

Hi,

I’m really curious on your opinions concerning the following design scenario:

Say you have an app with some sort of dashboard view. The dashboard consists of 8 cards, each of them displaying an individual piece of information from different collections from the servers mongodb. Frontend could be react or react-native, should matter for my question.

Since the data doesn’t need to be responsive/live, you’d prefer the methods first approach to get the data to the client.

Question now is: To be as modular as possible, you’d want each dashboard card to fetch it’s own data. However, this leads to several simultaneous Meteor.callAsyncs. The other approach would fetch all data for all dashboard cards and provide data to those individual component, so you’d only need one single Meteor.callAsync.

How much overhead do multiple Meteor.calls produce (mainly on the server), compared with a single call? DB ops on the server should be roughly the same (except from multiple redundant policy checks maybe).

Since I’m an amateur dev, pro opinions/experiences are highly appreciated :wink:

1 Like

You will most likely hit other limits like cpu/memory/bandwidth before hitting the limits of parallel methods from one client.

I haven’t had an experience to have parallel methods to be an issue and cannot remember any similar issue raised before.

I have versions of this same curiosity, and design thought. Great question @bratelefant

In terms of efficiency for its own sake, within reason, and stepping out of that case though ( one client ) and still in the situation of “not responsive” it seems like there is a cache opportunity here, or depending on how frequently the information changes, pulling a digest rather than live records?

I am thinking about this style where for example there is one Collection in my case, but many views of it, which might be better to see as “moments in time” which get archived in their own Collection then that is what is viewed in a dashboard, the snapshots already prepared.

Then the next question becomes: why have it be a database pull at all? Toward performance: I wonder the same, long-term especially with 5-10 years of data… can this be data in a bucket and be faster? Is this a dashboard snapshot with all the data prepared before arrival of visitor?

Amplifying the “desire for performance” portion but glad to know there does not seem to be a big hit for one client. And ever-curious to profile demand in the wild, or be able to estimate usage requirements. With the recent comments on scalability that seems to bode well though, and hardware is pretty much forever strong now, even in the bargain basement.

1 Like

Sorry, maybe I wasn’t specific enough. In my app I do not only have one single client connected. Currently I have ~1000 method calls per minute in peak times, so I always try to have performance on my mind when (re)designing my app.

Your design depends on the content of your cards indeed. Ideally, you would keep analytics of data you want to display in your Dashboard.

Please see an example of progress graph combined with “to date” data for the month or other periods and how I build this data:


I generate this data in some of the methods I use to save my data. For instance, if I receive a reservation, I save the reservation anyway and then the last thing is my method is to increment various numbers in my statistics such as gender, country, age, increment the number of reservations for the day I received it etc.

You may say this is extra work but I think it is one of those case where you write once, use forever and save $ forever.

2 Likes

That seems like the answer: A kind of "Persistent Stated Object" stored in the database, which gets incremented and pulled, versus doing real-time calculations ever. Nice reminder of sanity there @paulishca … And :clap: for screenshots and real example. Design solution versus Engineering :raised_hands:

Discourse needs room for :heart: and :clap: and :confetti_ball: all at once there.

Seems to use Mongo as if thread-safe Object across many client instances and server processes and agent threads the way Redis is being as if Queue.

I would do something like @paulishca said. You can run your analytics aggregation every x seconds or minutes, and store that in an analytics collection and you can expire the docs on that collection after x seconds so that it doesnt increase infinitely. And even better you can cache the DB response until it changes or for X time so that the DB is not hit that often, and you can also cache on client so that the app server is also not hit as often.

So a single subscription to a document queried by orgId, and sorted by createdAt -1, with the right indexes will be very performant. Or a method call every minute will be even better because is more easily cacheable.

I understand. Did you experience any issues with thousands of method calls per minute?

I never had that experience wherein the number of concurrent methods were the issue. In a server instance, the limits that we normally reach is an issue with cpu or memory due to processing done by those method calls. So before we can exhaust the number of method calls allowed per instance, we have to scale anyway so we never had to think about combining 8 method calls into 1 (as an example) because it was never the issue per se.

If what your methods do is just pull data from database and return to client then you may want to focus on how to reduce numbers of database queries. If combining method calls could reduce numbers of database queries then try it.