Hi Gazinhio,
All of the aggregation operators (count, approximate count, sum, product, median, max, min, average, and any others I’m forgetting) run on the server in a bunch of situations. In fact, I think they’re likelier to run on the server than not. The main situations where we run them client side are usually when the search expression is complicated and can’t be turned into a database query, when there is an advanced filter applied, and when we can rely on client side optimizations (such as if the underlying search has already been run and the results are in the client’s cache) so we don’t need to request much new information. In the example you gave, there aren’t enough specifics for me to say if the aggregations would run client or server side. But one way to think about it is that if the data you want for the text boxes is already on the items associated with each RG cell (e.g. each RG cell’s item has a field that is a list of values, and you want a count of that list), we will probably perform the operation client side. A contrasting example where we would perform the operation server side is if each RG cell’s item has a field that is a list of things, none of those things are already loaded on the client, and you want a sum of each of those thing’s X field.
I should also be clear: the cached aggregation operator shouldn’t reduce the number of live update responses from the server, even if it makes those updates a lot less expensive to calculate on the server side. If underlying data changes, the server will still notice, recalculate the cached aggregation, and send it to the client. But that recalculation will be a lot faster because it will rely on the cached value instead of going to the database (if it’s within the 30 second window of the original computation), and then the client will just ignore that response because it will see that the value sent from the server is the same as the value already being displayed.
Also, a word of advice: there are two different kinds of performance concerns to consider when thinking about data requests: how intense of a load is put on the database and how many network requests go between your app’s client and our servers. The intensity of the load on the database is kind of self explanatory in the cases where you have a very large query/computation. My point, though, is that when the query/computation isn’t too large, client side computation isn’t uniformly less performant than a server side one. What makes client side computations expensive is most often the round trip time of requests to the server for a lot of data, as well as the overhead of having more/larger data to handle. So if the client needs information that it can only get from the database, then it is faster to have the database do the aggregation work. This is not so much because the database is faster than the client, but because once the database has done the computation, the size of the data that needs to be sent to the client is much smaller, which will require less handling work for the client and possibly fewer requests/responses sent over the network. But if the client has most of the data it needs already to perform a calculation, it’s definitely more performant if it just does that calculation right away, since it saves the round trip time to the server.
So in general, if you’re worried about the performance of a computation, we have a lot of logic to try to be smart about doing computations in the smartest/fastest way, and the main limitation to our ability to do that is if we can’t make the right assumptions about the type of query that is the best to do. So a good rule of thumb is that when choosing how to define an expression, go for the most direct way, for what you want. For example, if you want to apply a filter that can be specified by putting a constraint on the search, do that instead of using an advanced filter. If you want to get the max value for a field of a type of thing, use the max operator instead of sorting the search for that thing and taking the first item. If you want to perform an aggregation, call that aggregation directly instead of putting unnecessary operators in between like the group by operator. The closer the expression describes what you want, with the most specific operators we provide, the less likely our logic will make an assumption it shouldn’t make and do something less efficient. I hope this gives you some food for thought!