I recently worked on an app for optimizing because certain queries were eating up WUs. The optimization decreased the WU consumption to a certain extent.
This made me wonder, what are some of the things you guys do to ensure your app remains optimized wrt WU especially for analytic heavy apps with extensive database?
This is something I’m still working through, but if I notice a particular search was done multiple times on a page load (meaning several different elements all performed the same search to set conditions, for example), or while performing a workflow, I’ll consolidate that search either by loading it into a hidden group, or a custom state, and then reference that instead.
I mostly work on apps used by logged in users, particularly internal tools and enterprise / B2B apps. The WU cost isn’t a real concern for these as users are high value, and it’s generally fine to just use WU wherever you need because it can be afforded.
WU optimisation is really important where there’s a lot of people who use your app without paying. That means the marketing pages need minimal search expressions (you can cache data in a single Thing on a Settings/Environment Variables data type).
In terms of other stuff, and I have no guarantee that it works:
Instead of Do a search for X in each cell of RG, do the search outside of the RG and in each cell reference Search:filtered:first item. This generally only does one search and filters client side, rather than doing a search for each RG cell.
Schedule API workflow on a list >> recursive workflow
I’ve never really had a use for satellite data types but that is a route you can go down if you have a particularly heavy data type and must save the WU (but it costs WU to maintain a satellite data type…)
Offload some functions off of Bubble. I know that’s not particularly helpful to some but stuff like taking chunks of texts to embed and upsert to Pinecone runs orders of magnitude quicker in a Google Cloud Function than the Bubble backend. I mean 20 seconds vs 40 minutes.
It comes naturally when you work in the paradigm of using states to store search results instead of plugging searches as data sources. Advanced filters work just as well as searches in data sources when used properly. It slows down when filters are either complex, run through extremely large lists (thousands in my experience) or searching through fields with large values. Sometimes is a combination of all those things that slow down the filtering process.
I use satellite data a lot. Usually some sort of index for searches.
While it should be standard practice I’ll bring this point up: Break large data into multiple datatypes. Until Bubble allows us the feature to receive values from specific fields (without using any API workflows) it’s how I control the amount of data that gets loaded to the client. What I cannot limit using privacy rules I break them up into different datatypes. So a datatype that usually has ABCDE will now be datatypes AB1 and CDE2 (1 and 2 are links to each other). This gives me more control over data that gets loaded to the client. For example, why would you want to load a list of User Recipes, when they are in a profile page.
Another method I use is to store complex data as text. This can end up as a JSON or some pseudo JSON like key|value||subkey|subvalue. Depending on what I am using it for. A quick regex formula will help extrapolate data. In terms of WU, it can blowup in your face if you are not careful but for my use cases it’s more about load speed (less searches needed), speed of extrapolating the data (regex in Bubble is still extremely fast) and sortability (i can sort complex data using text). For example; i store form responses this way. It gets loaded to a responses table (i use repeating groups), gets extrapolated and displayed accordingly using regex. My testing so far have shown that this is also the fastest and WU friendly method of updating a value of a row item, instead of having form answers as individual data.
In the end, good habits, good planning and awareness of how your workflows will costyou WU will drastically reduce your WU usage. You don’t need to be precise with your WU with spreadsheets and stuff, just understand the weight of each WU related cost in relation to your Workflows. For my sanity i don’t nitpick my WUs when developing and optimizing. We don’t know exactly how much water and electricity we use, but we know to not leave the faucets and switches on when not in use. I leave the nitpicking during testing and debugging.
I also rely on this type of data structure, more so for scalibility than WUs. But I have a question for this. Doesn’t bubble still load the details of the list linked?
Using your example if I was only wanting to view AB1 all the linked CDE2s would also be loaded. If I look into debug data, I can see the detailed values.
No, not unless you are referencing values from it in a repeating group. If you have a repeating group that is data source of AB1 and in the repeating group you never reference a value of current cells’ AB1s’ CDE2s, then it doesn’t load all the data from CDE2s and instead it is just the unique ID of CDE2s that gets loaded. But the moment you reference one value from the CDE2s, then all the data values from CDE2s is returned.
In regards to satellite data types, consider how often these values are going to be changed, because everytime you change AB1, you will need to change CDE2, which will increase WU costs for modifying data types. Don’t forget for every single data type, every single time you create, delete or modify the data type, you are charged 0.05 WUs for a database trigger scan (something completely ridiculous that Bubble does because they do it even if you have no database trigger change events in the app).
It has always been the case that you should avoid at all costs nested searches, which was not because of WUs but because of speed and performance issues. But, now that WUs are involved, it is even more important to avoid them.
Best advice in this thread so far. This allows you to have super quick filtering in other areas of the page as well. You can also find ways to have data types that are more static in nature, but searched often to keep those values on the page so that they are loaded without touching the server at all.
If your app is on WU pricing already, the improvements to workflow on a list are available, which does make them faster and more reliable and in respect of WUs, less costly than a recursive backend workflow.