An Update to Workload, Plus More Transparent Calculations

While it is true that RDBMS will cache row counts on tables and sub-tree node counts on index branches, quickly getting those counts in Bubble will not work as expected because every application, EXCEPT those on “dedicated plans”, are all in the same database. From what I have heard they are using a substantial replicated Postgres instance. To get this to search quickly, or even return counts quickly, per application, would require fastidious attentiveness to the structuring of the indexes and keys. This gets even dicer when dealing with an underlying highly normalized table structure that can store the representations of Bubble’s versioned and dynamic “things”. Roughly I would expect the main value store in Bubble’s Postgres to look like:

CREATE TABLE BubbleNormalStore (
    ApplicationName TEXT,
    ThingName TEXT,
    FieldName TEXT,
    FieldValue TEXT,
    FieldType TEXT,
    ThingId TEXT,
    Created TIMESTAMP,
    Deleted TIMESTAMP

But that is all and educated guess.


Anybody else think it’s not too much to ask for a bubble representative to actually stick around to answer questions/ defend their pricing scheme?


Does a “make change to a thing” take up more WU as a fronted workflow or a backend workflow?

I put lots of stuff into backend to optimise my app & keep capacity down, but now I’m wondering if this will actually use up more WU.

Does anyone know the answer to this?


Putting everything in the backend would make the capacity higher before and after this price change

I absolutely agree @Kent, to charge via WU, Bubble will need to take just about every possible combination of search result and expression into account.

I wonder how many WUs Bubble is using to calculate WUs? Maybe that’s why they’re so expensive.


To help, I’m humbly putting for consideration a new pricing system that combines what the community and shareholders have communicated to be valuable for them, being simple, predictable, auto scalable and tied directly with the resource consumption of each app:

Keep the capacity plans and charge more for them, if needed.
For auto scaling, charge per each minute where the app was exceeding 100% capacity, instead of killing workflows at that point.


  • Auto scaling is optional (app admin can turn it on/off ). If off, workflows would be killed when app surpasses 100% capacity.

  • Minutes over 100% capacity would have a price, minutes over 150% capacity a higher price, minutes over 200% capacity a higher price and so on.

  • App admin can setup alerts for when app has exceeded X amount of minutes over 100% capacity (or any % capacity, customizable alerts).

  • App admin can setup a monthly capacity overage cap in USD for minutes spent over 100% capacity.

I set my capacity overage cap to be $100 monthly. The price per minute over 100% capacity is $1 and the price per minute over 200% capacity is $2.

In the current month, my app have spent the following in capacity overages:

  • 90 minutes over 100% capacity (90 mins x $1 = $90)
  • 5 minutes over 200% capacity (5 mins x $2 = $10)
    Total spent in capacity overages until today = $100

Since I set my monthly overage cap to be $100, I’ve reached my cap. This causes auto scaling to be automatically turned off for my app. I would be able to turn it on again, only if I increase the $100 overage cap that is now fully consumed.

That’s it.

I believe Bubble could apply this pricing system leveraging their existing architecture, they already measure capacity and also minutes where the app surpassed 100% capacity.

Which pricing system do you think is better?

  • This pricing system
  • This pricing system with some changes (post your proposed changes below)
  • The WU pricing system
  • A completely different pricing system (post your proposed pricing system below)

0 voters

Just throwing some ideas to try to help you as you have helped many of us with Bubble. Thank you for listening.

@emmanuel @josh


Capacity pricing certainly created a beneficial economic incentive to self-throttle the workloads and distribute them uniformly over time. Get a lot done, but get it done slowly.


@Kent, I can’t vouch 100% on the database side for what Bubble does on the backend when asked for Search for Things :count. But I do know the Bubble plugin API very well and we know some things about how this all works in that scenario.

First, I do this in some of my test apps and it’s true that even with a very large database of some Thing (like more than 150,000 Things of a given type), Search for Things :count in a text element, for example, returns nearly immediately and doesn’t actually cause the values of the Search for Things part to be fetched.

But there’s some subtlety in how this works. The results of a Search are a single JavaScript object (which we call a List – I use capital L here to distinguish this object from a “list” (a Bubble array) in the generic sense). The List object has two methods on it: get() which allows us to “unpack” the List and turn it into a JavaScript array of whatever values it contains, and length(), which allows us to inspect how many items are in the List (this function returns what you know as the :count, in Bubble terms).

So, as you can see, we can actually know the length of a List without unpacking any of its items. It’s actually this process of unpacking the items with get() that, in the case of a list of Things, causes the Thing objects to be fetched from the database. And this is the “slow” part of fetching a List.

I take advantage of this in List Shifter, BTW. Well before any items are fetched, I publish the result of List.length() to a numeric exposed state that tells you the number of items in the List (it’s called Num Items or Number of Items or something like that). This is sort of invisible because I don’t trigger the initialized/updated event until everything has been done, but this Number of Items state gets published pretty much instantly and well before the items themselves are published to outputs like Original List and Shifted List.

So, if Search for Things :count works in the same way in a Bubble page as it does in a plugin, I guess one of two things could be going on with respect to WUs: Either the search operation itself (not the count part) essentially “gathers up” all the items, sending us info on how to eventually get() them and this gets counted as “that many things could be returned by the search” (even though in this case we never actually get them), and this might be a miscalculation on Bubble’s part.

But, on the other hand, Bubble doesn’t really “know” that we’re never going to get the contents of the List and, in the page, it might in fact just begin fetching them just in case. (If a List contains Things, those Things are also a type of JavaScript object that again has some methods on it to allow us to access the Thing’s fields.)

It’s probably only in the somewhat weird plugin case where we might ever exploit this, in the way I describe with List Shifter. When it unpacks the List, if the List is full of Things we actually don’t fetch any of the values in the fields – not even its unique ID – we just leave the Thing objects as they are and publish them to the Original and Shifted List states. So any further data fetching only happens when you eventually reference those fields somewhere else.

I can’t be sure about how all of this truly works with respect to the db. (Like, if a List is a List of numbers, do the numbers themselves come along as part of the List object? Or are the values only retrieved from the database when we actually execute .get() on the List? I have no way of knowing because the only way to “see” the constituent items in the List is to use .get(). I suppose I could inspect the Network activity but that wouldn’t 100% answer the question.

Anyway tl;dr: The count/length of a List can be determined without looking “inside” the List and, this action is pretty much instantaneous, and if you never unpack/get the List, is it incorrect to charge you for that?

Note that I have not inspected this sort of thing with respect to WUs yet, but I guess that’s another very nichey-niche thing that I need to understand now. No point in looking at this further until we see the new WU consumption in our apps tomorrow or whenever that gets released.


Few ideas:

Create an official payment system plugin instead of Stripe and take same cut, we earn, you earn.

Limit free apps to 3.

Deactivate any free app that is inactive after 30 days.

If removing WUs is out of question, 100x every plan.


As someone who loves Bubble, I say this with kindness and intent to be constructive: pricing should not be this hard nor confusing, and it shouldn’t meaningfully detract from the experience using the product.

I’ll hold off on too many judgements until the WU-reweighting tomorrow, but I’ll be curious to see:

  1. Will there still be users will have their monthly cost increased 3x? 10x? 50x? These are massive changes for a lot of folks.
  2. Computing power is cheap — so why doesn’t it feel this way? In today’s update, I’m not sure why @josh, @emmanuel, and team didn’t simply 10x WU allocations across paid plans? Bubble users want to pay for functionality, not computing power. I get that there need to be upper bounds to prevent abuse, but there’s no reason computing power shouldn’t feel generous. ¯_(ツ)_/¯

There sad part…there was a better way that would have regained trust.

The team could have walked back once more, and said “we messed out the pricing rollout of last year. And despite our best intentions, we messed it up again this year. We feel terrible, and are going to try this once more time in a way where we remain sustainable, but it’s far more collaborative. In a way where 99% of users won’t have to worry about about 3x, 10x, or 50x price increases. Third time will be the charm.”

Instead, by doubling down on WUs, the team is doubling down on something that’s confusing, scary, and intimidating for a typical non-technichal user. I’ve always loved that "user-centric is a core value of Bubble — but this ain’t it.


Excellent post. Exactly what we’ve walked away from this last weekend as well. Even if things get back to “normal’, our strategy has changed for the coming year.

It’s effecting our hires and how we build new functionality/workflows moving forward. If Bubble does indeed offer exports, even that’s a function that could be taken away or punitively charged for.

We’ll likely not move away completely, but we’re positioning for stronger portability and failsafes.

So, on a dashboard which has say 50 different Search:counts, could it potentially be cheaper in WUs to use List shifter and not actually shift the list, just display the num state?

1 Like

I just don’t see how Bubble will be useful for low cost SaaS anymore. The appeal for me to use Bubble was, I could create a SaaS and undercut the competition, make a decent profit while keeping overall expenses low. If I were to start on the new pricing today I would be totally in the red and the only way out his heavily butchering what I’ve created. I’m starting to regret every single second I’ve put into Bubble that could have been spent learning something else.


It needs to be in the debugger, step by step actual WUs generated. Backend process should have the same for each process and sub process defined in the step boxes, showing last run costs.


Well, not at present. (1) if this did work, it’d have to be a new but simple plugin, (2) if referencing Search:counts really does use a lot of WU, then, well, it uses a lot of WU. The Search expression is evaluated before a plugin does anything with the result (the List), so if this is being computed in a somewhat unfair way in this instance, it just is what it is.

But the original observer of this makes a pretty good point! (I’m guessing what Bubble would say about that is that – kinda like I did – well, ya see, here’s how that works and it’s not an easily changeable thing. Of course, there could be a different expression for this – you know, like Get Count of Things that would get charged in a more sensible way, but I wouldn’t hold my breath on that.)


Well Said.

1 Like

I added this feature idea that I think would help making the WU logic more palpable:

Inform WU consumed directly in the related workflow and action, in the “workflow” tab.

I understand that you’re releasing an update that will allow us to see the WU consumed in each workflow and action in the server logs, but it would be much more user friendly if we had that directly in the related workflow, in the “workflow” tab. I imagine this as a little badge showing how many WUs the action consumed on the last time it ran.

It would be even better if we could have an estimate of how many WUs will be consumed when we’re creating new workflows. So imagine that I’m adding a new action that creates a thing in the database, you show me that I should expect this action to consume aprox. 2 WUs (random number as an example).

The combination of these 2 features would make it much more easier to understand and predict how the actions impact the WU consumption since the development phase, and would help us to incorporate the WU logic.

You can upvote here if you like it.

1 Like

So 100K WU’s each month ir just one time thing?

1 Like

The power of no-code is in it’s simplicity, and every step of progress made in this industry is to make things easier and more powerful.

I totally understand what you are trying to solve with this pricing model, but it seems so out of place in this industry and your target market. Capacity and throttling is a lot easier to understand than this workflow model.

The pricing model that @pachocastillosr suggested above makes the most sense and would love to see more thought given to this.

Like many have said, this model gives alot of uncertainty, even if things improve significantly on the calculation side, having to constantly monitor our workflow units and optimize constantly detracts us from the main goal of building apps quickly and cost effectively.



Não sou um grande influenciador aqui no Brasil, mas tenho centenas de pessoas que estão no Bubble por influencia minha.

Confesso que tive a impressão da mensagem ter sido escrita com uma vibe de:

Pisando nos ovos que já estão quebrados!

Não vou tomar nenhum julgamento precipitado e esperar para calcular essas “melhorias”.

Posso estar enganado, mas hoje foi decretado a mudança do propósito e público-alvo do Bubble.

Vou aguardar as análises do mercado desta quinta e sexta, meus cálculos internos e preparar um vídeo bem transparente com minhas opiniões finais e os impactos de mercado que acredito.


I’m not a big influencer here in Brazil, but I have hundreds of people who are on Bubble because of my influence.

I confess that I had the impression that the message was written with a vibe of:

Stepping on eggs that are already broken!

I’m not going to make any snap judgments and wait to calculate these “improvements”.

I could be wrong, but today Bubble’s purpose and target audience has been changed.

I will wait for the market analyzes this Thursday and Friday, my internal calculations and prepare a very transparent video with my final opinions and the market impacts that I believe.