Workload Units Charging very Inconsistent

In an attempt to make sure I fully understand the Bubble WU metrics, I’m taking a bit of a deep dive and doing some simplistic tests.

I ran this test twice so far and see dramatically different WU charges for the same things, while also seeing that some of the things are not getting charged consistently, but should be.

First test ran had the following setup

Result on Screen




The WU metrics tab showed the following charges



The deleted search in the screen shot above is the search for Ports…The reason it shows as deleted is that in my testing, from the page, I deleted the container group…I afterward pressed the Undo Button. Unfortunately, that uncovers another bug, which is that the ‘Deleted Search’ should not be shown as a deleted search in the metrics tab anymore, since it was basically ‘undeleted’, but I digress.

So, in the subsequent test, I had to do because the first results shown above confused me a bit, since the search for Ports was only 0.37 WUs but the search for Ports items until #4 was 362 WUs…That search of Ports items until #4, was not actually structured that way at the time I ran and got those results, it was simply searching for Ports in an RG with Fixed # of Rows at 4, so it made sense that the system would charge 362 WUs as it fetched 40,000+ entries and converted to text. After seeing that I changed it so it was items until #4, which dramatically reduced the number of results returned (ie: only 4).

Now, testing again, after making the alteration to the RG for text based, using the items until #4, I see very different results.

Now, my search for Ports is costing 56.24 WUs instead of the 0.37 WUs it previously cost…I made no changes to that RG and search, the changes were made to the RG with text of items until #4…so Why would the cost of the same search be 152x more expensive?

Also, I see no WUs charged for the text based RG with items until #4

Adding to confusion, a test ran prior to this had a dramatically different result as well, I was charged 298 WUs for the same search…and yes, these numbers are for a single search, as I checked against the page load metric


I’m continuing to run these same tests in a hope of uncovering what is the reason for such dramatically different charges for the same search, on the same page, performed at different times (like 10 minutes apart)

1 Like

Now I’m seeing an individual data request, that I can not drill into, in order to see what it is from

I also see the RG text based as 0.47 WUs

The main search for Ports in the RG of data type Port is not showing as a Search now, but it does show as an aggregate search and real time search

And that aggregate search of 0.20 is not actually attributed to the search in the RG itself, but is instead attributed to the Text element that references the RG of type Ports count. This has been explained to me by support and I understand this now thanks to @georgecollier reply in another post. But what doesn’t make sense is why the cost of the search in the RG is not applied as it was previously, with such inconsistent and dramatically different costs ranging from 0.37 - 298 WUs?

I’ve continued my tests with video…will be sharing with support. None of what I have seen really makes any sense.

For example, at 1:55PM I was charged 361 WUs, then at 3:16PM I was charged 341 WUs for the same search.

Also, it doesn’t make sense to me that a setup with a search for thing and the data type of the RG is that thing, with the RG that has fixed number of rows set to 4 incurs a WU charge equivalent to fetching only 4 records (this part makes sense), but when you have the RG set to type Text, with datasource as the same Do a search for thing, with a client side operator of format as text, with the RG set to fixed number of rows of 4, that the WU charges for fetching ALL things in the DB and not just the first 4, but if I set that search to precede an operator of items until 4 it does charge for the first 4 items only, and not ALL, HOWEVER, the charge is higher than when the RG data type is set to the Thing and not Text (difference of 0.10 WUs).

Do a search for Things in a repeating group with 4 fixed items should cost 0.3 WU + 0.015 * 4 = 0.36 WU (plus a negligible amount for data returned).

It should not return all of the data in that table unless you’ve asked for it elsewhere - only the first four items.

Is that not what you’re seeing? What are the exact elements on your page, RG settings and search source that lead to 300 WU for a search?

That is what is happening somewhat consistently.

Did not

That is where the confusion comes from. Whether it is a bug in the metics tab themselves or the way the charges are getting incurred.

Setup is the same. RG set to fixed rows of 4. Same search performed.

Added to the page another RG set to fixed rows of 4, type text, same search performed as the first RG, but apply operator of formatted as text.

In first test, the 300+ WUs was applied to the second RG - doesn’t make sense as the format as text operator is client side, so the search should just return first 4 as the first RG does.

In second test, I deleted the second RG, then the first RG incurred charges of 56 WUs.

In third test, I used the undo button to get the 2nd RG back on the page, applied operator of items until #4 then the format as text. The WUs showed 0.47 all applied to the second RG, but none applied to the first RG…this doesn’t make sense as it should just be 0.37 since the same search is performed essentially.

Over the course of testing for 2 hours on the same page with different variations (ie: items until in 2nd RG or not, both RGs on page or not) got results varying from 361 WUs to 0.37 WUs…in fact for one test, the same search had 341 WUs applied and an hour later it was 361 WUs.

Doesn’t make sense.




It does make sense.

When you Do a search:format as text, that necessarily returns all data from that table, as it needs to return it into one text value (that’s the purpose of format as text). That’s doing exactly what you tell it to: Find all of the Things, then format them as text, then display them in an RG. The fact the RG is only 4 items is irrelevant because the :format as text requires returning them all - the RG isn’t ‘aware’ that it only needs 4 items - all it knows is that it has to take a text:split by something.

Do a search : items until #4 : format as text will be fine.

And the same search and setup incurring different costs at different times makes sense?

Is the format as text an operator on the server or the client? I ask because I’ve always had the understanding that any operators that are applied after the DO a Search portion of the dynamic expression are happening client side, and not server side. This is why it has always been best practice to avoid the :filtered operator and instead use the constraints on the search itself.

So, when doing a Search for Things and the RG is set to a fixed number of rows, as Bubble support explained it and is seen in the RG set to the type of thing, it only returns the first 4 items. So what doesn’t make sense is that if the :format as text operator is a client side operator and the RG of type text has fixed number of rows, why then does the Search happening on the server return all results instead of just the first 4, since the way the server processes the search for the RG of type thing by referencing the fact it has fixed number of rows…this should be applied to the RG of type text as well, despite the fact that a client side operator of format as text is applied after the search.

Server side includes:
:count (this is the most obvious example as you of course wouldn’t want to return ALL data from the DB to the server just to count it)
:items from / to
:random item

Client side:
Most of the :each item’s X stuff

It always varies depending on the specifics of where it’s used.

When you :format as text in the browser:

  1. Bubble retrieves the data from the server according to your search constraint
  2. Once it has retrieved ALL of the necessary data, it runs the :format as text from the search results

Do a search items until #4 : format as text:split by is not logically equal to Do a search:format as text:split by:items until #4 (they will not always be equal).

Do a search items until #4 : format as text:split by

  • will only return first 4 items from search
  • can return unlimited texts (as each item could have multiple of the thing you’re splitting by)

Do a search:format as text:split by:items until #4

  • will return all items from the search
  • can only return 4 texts
  • if there are multiple instances of the split by character/string, then this might not display all of the Things you’ve formatted as text

This is absolutely the correct behaviour. All :format as text does is take all of the texts that you provided in your initial search, then make them into one text. Again, I’m not saying it’s intuitive but it’s definitely behaving how it should.

That is understood and not the point.

The point of contention is why the difference between an RG set to fixed number of rows of 4 which is set to type thing, only gets the first 4 items returned and charged. Whereas, an RG, setup the same way with fixed number of rows of 4, with same search, set to type text, but has Client Side Operator of format as text is getting charged to retrieve ALL items.

Are you implying that the format as text operator is not client side? Or are you saying that it makes perfect sense that Bubble will return only the first 4 results to the RG set to type thing based on the fixed number of rows, but will not adhere to the same mechanisms to return only the first 4 things if the format as text operator follows the search even if the fixed number of rows is 4?

Screen Shot 2024-09-01 at 5.05.46 PM
Screen Shot 2024-09-01 at 5.05.36 PM

For me personally, logic would have it that a client side operator should not cause the search server side to return more results.

For RG of a Thing with fixed rows:

  • the server knows it only needs four items
  • it therefore returns only four items

For RG of text using Do a search:format as text:

  • Even though you’ve set fixed rows, :format as text needs all of the Do a search to run
  • The DB has to fetch everything and return it to the browser to run that operator, regardless of how you display it later (e.g in an RG)

That’s why if you have a huge data search, it takes longer to display a :format as text (irrespective of whether it’s in an RG or not), than it does to display the Things in an RG - because in an RG, it can lazy load them gradually, but format as text requires all of the data to run.

Okay. I just setup another approach.

I have an RG with :format as text to reference the RG of the type thing…the RG of the type thing still with fixed number of rows retrieves only 4 items…then I’d expect if that is all it has retrieved, then the reference to it will only have the 4 items, but it causes it to retrieve all items.

Screen Shot 2024-09-01 at 5.11.06 PM

I’m seeing similar with a pagination. What I’m finding in pagination it makes more sense not to reference the RG with fixed number of rows, and instead just do a search :items from :items until…the results show a difference of 3.72 WUs when referencing the RG with fixed rows follolwed by items from items until compared to 2.82 if have the display RG just do the search with items from items until.

Screen Shot 2024-09-01 at 5.16.06 PM

The above is cheaper than the below

Screen Shot 2024-09-01 at 5.17.24 PM

This is another misconception about how Bubble searches work.

When you have a hidden repeating group, the number of rows in it doesn’t change the result of the expression if you reference it elsewhere. All that ‘fixed rows’ does it say to Bubble - I don’t care about the rest of this result so don’t tell me about it. That doesn’t mean that the rest of the result doesn’t exist. If you reference that RG elsewhere, unless you’ve also set that RG to only return X items, then it will get all of the results as it should.

Take a Repeating Group ‘var - contents’ which is a List of Contents from Do a search for Contents. I’ve set this to be 4 rows so it displays only 4 items, even though there are 10,000 Contents in the DB.

When I display that RG, sure, it’ll only retrieve the first four items. However, if I reference ‘var - contents’ somewhere else, we’re not referencing just what’s displayed - we’re referencing the search expression.

If I reference var - contents in another RG, then what I’m actually doing it referencing the RG’s datasource, not what it’s displaying.

So, the example you gave is logically equivalent to just Do a search:format as text

FYI this is not true - although it seems to be a common misunderstanding (not entirely relevant to this thread, but still worth pointing out).

Using :filtered doesn’t inherently mean the filtering is done client-side.

It depends on what the filter constraints are.

If the constraints can be applied to the database query, then they will be - even if you add them with :filtered after the search expression.

For example, a search for Users, with no constraints, filtered with a constraint that can be done on the DB query (e.g. email is myemail@email.com) will only return a single User from the DB, even though it’s using the :filtered operator after the do a search for expression.

But any constraints which can’t be applied to the DB query (such as calculated or modified values, self-referencing values, or values of related datatypes etc.), will be done client-side. And in those cases, due to Bubble’s very limited DB query capabilities, you have no choice anyway than using an advanced filter (aside from adding additional redundancy to your database), so it’s unavoidable.

It’s best practice to avoid using :Filtered and just put the constraints on the search itself when you can purely because it’s simpler, and more logical (rather than adding unnecessary complexity).

5 Likes

That makes sense.

Tough times to figure out all the new nuances of how to structure an expression to optimize for WUs…guess the way forward for a lot of things is to use the items from items until operators.

I mean, maybe, depends on the use case. I haven’t had a need to do this at all.

The most important takeaway from this thread if anyone is reading is that :format as text takes a list of data, and converts them to a single string. To do that, it needs all of the relevant data, in all cases.

I wouldn’t make that statement…it is something to take away from the thread, but there are still issues not hashed out like why the inconsistent charges for the same searches performed at different times, hence the name of the thread.

Pagination

1 Like

This should be qualified with the context of having the search as an RG’s data source.

1 Like

I don’t think there’s any other case where :format as text can run without retrieving the entire list it’s supposed to run on, so it should be true in all cases.

This topic was automatically closed after 14 days. New replies are no longer allowed.