Bubble [ONLY] WU Optimization strategies and results

I’m starting this topic so everyone can share WU optimizations they did, but only by updating their Bubble APP without using external tool (DB or backend for example).

I think this post will be helpful if you share:
A) App Purpose or main feature
B) Where the WU was mostly consummed
C) What did you do to reduce WU
D) What is the end result?

So I’m starting with two apps:

A) Call Center Portal. This app is Connected to AWS Connect. We receive and create call from there for a team of 50+. This app is also connected to an external system (API) that could contain info about caller and related items. User can leave notes about call, reasons for calling and send all data the other system. This app receive more than 1200 webhooks/days.
B) WU was mostly from Search related to call data. Because of different parameters, we was performing a lot of different search. At the end, this was not needed at all (but this happen often when you keep adding more and more features!)
C) We completely review all search. All Call have a unique ID and an initial webhook of “queued”. For the RG, we now only search for queued and the only field we need at this step is the unique ID (RG is now of type text instead). Inside this RG, the group itself search for most recent webhook item (this is updated live, each time a new webhook come in). Most of the conditionnal have been modified now to only consider data available in the last payload. Before, a lot of conditionnal was searching for specific data (example where Search webhook connected date’s count >=1 (we also did change all the 0 conditionnal if needed), show a different status, now instead we use Parent group webhook connected date is not empty).
D) We was around 950 000 WU a month and now we are down to 441 000 but we got a 10% increase in number of calls since this update. This app was on pro plan at 119$ a month and we are now at around 70$ month.

Second case:
A) A user portal. User can see their own data, do some calculation, get financial informations. There’s a lot of API Connection in this app. Each month, we are importing data from a large PDF that we need to split and parse (we are using pdf.co for that). 1500 items to process (split) and after, for each of time between 5 and 25 lines to parse from a table.
B) Each import was creating a spike WU of 150 000. The other main WU consumption was from webhook we was receiving from another system.
C) The first step was to convert the old recurring backend workflow for the import to a SAWOL. Because we moved to this function, we was also able to reduce the number of actions in WF. The second thing we did was to move from a webhook receiving data to a fetching data instead. The system that was sending the webhook could trigger a lot of time everyday. Instead, we are now fetching for data when the user login to their portal. There’s a small delay for user to see fresh data (2-3 seconds) however, because we fetch the data as soon as they login, in most case, user doesn’t see the difference.
D) From 850 000 WU, we are now down to an estimated of 150 000 WU a month. We only moved at the beginning of this month so this app was on a 32$ personnal and will probably go to starter plan for the same price. BUT, the import process that was taking 24h to complete now take 2h and only cost 25 000WU.

Working on another app and I while keep you posted on results.

Thanks to share your tips so everyone can optimize their apps :wink:

19 Likes

fantastic idea. I think everyone would benefit from hearing other users talk about how they have approached optimizing their apps!

5 Likes

One app we started working on recently had a lot of recursive workflows. For each, they used a List Popper SSA to get the first item of the list, remove it, and pass the remaining list to the next iteration of the recurisve workflow, rather than the native Bubble option of using List of Things:first item and List of Things:items from #2. We’re in the process of replacing these actions with native counterparts, and they’ll probably save about 500,000 WU a month (their total WU is 4,000,000/mo). That should save them about $780 a year.

Another app we audited for workload optimisation had 8 figure workload unit consumption. In their backend workflows, they’d often use Make changes to a List of Things not to change things but to store it as a variable to use in the workflow. Then, they’d filter that variable. That’s one search to return the entire data table, and another to filter that. Whilst this fortunately doesn’t charge the 0.5 per edited item, it returns a lot from the DB, and costs more WU to filter. By removing stuff like this and just using normal inline dynamic expressions, we think we’ll save them 5-10 million WU a month ($5k-$8k annually!).

In one of our AI clients’ apps, we frequently deal with file uploads that allow users to chat with documents. We have a file browser, and used to store the file’s extracted text directly on the File data type (this was fine for the MVP). That meant that browsing the file browser used a ton of WU, even when the file content wasn’t displayed, because it was downloaded to the browser anyway. We created a satellite data type instead, so that we only load the File’s extracted text when we really need to.

7 Likes

Thank you so much for taking the time to do this post.

Although a lot of it is still way over my head when it comes to Bubble, I’m bookmarking it along with all the other bookmarks about Bubble :laughing:

A big problem when you’re new is not only trying to learn Bubble, but then learning how the WU system works and trying to figure out how to optimize. I’ve been working on my app for about a year and I love Bubble…I’m sure I’ll get better as I go.

Good job though, and thanks again.

1 Like

If haven’t ready, check out the new official tutorial Youtube videos by Gregory on WU, and the updates Bubble manual. There’s actually a lot of of good info now, that even experienced Bubblers miss out.

As the now gone @keith used to say: RTFM

5 Likes

Thanks.

I’ll look those up.

I love his videos. He’s brilliant when it comes to Bubble, and I love the way he makes it so clear.

1 Like

Our application houses dashboards and other functions for our clients to view/manage data from their Shopify stores. These number ~120 at the moment and is an ever growing list.

During the initial build, I had 0 experience with app building, as I’d only ever handled web design on client stores, so I made a fair few infrastructural errors:

  • Polling instead of webhooks: This was probably my largest misstep, and one that didn’t matter when we initially launched with 5 client stores. With scale however, this turned into a huge drain on time and resources, as I was eventually polling 100+ shops every 30 minutes, some of which returned nothing.
  • Overuse of recursive workflows: Since these output tangible, actionable data with each run, they are still quite generally my preference, even in spite of bubble’s upgrades to the schedule on list action (still waiting for step by step output/controls!). That said, I quite often found myself defaulting to them when they weren’t necessary, which is probably another symptom of not needing to consider wf units previously.
  • Complex constraints/only whens: I was quite surprised to see just how many wf units my conditionals, particularly “only whens”, were consuming. This occurred largely due to extensive searches of the database to check for the existence of items (we had an issue with duplicates very early doors so I became quite paranoid). I have since compromised on almost all of those by only checking items made in the last hour, instead of the whole database, reducing wf unit consumption by about 300-400k/month.
  • Database structure: I’ve always tried to use as few fields as possible on all objects in the db, relying on nested objects to grab a single field stored there instead. I found out later that this would often force the use of filtering on nested arrays to get the correct value. I’ve since gone through and in most cases added the field(s) from the nested object to the parent or joint datatype, making searches infinitely simpler to define, and leagues more performant.
3 Likes

Do you mean you’re now duplicating the data in a separate field? Or linking it (Thing A’s Thing B’s Field A)?

As much as it pains me, I am duplicating the single field that I need, as opposed to linking the entry. Linking is fine for a lot of use cases, but has really fallen down on large database searches, especially when I just consistently need one field on a linked entry.

1 Like

Yeah I do the same for certain fields. Sucks but better than searching.

1 Like

I also do it for sorting

1 Like