The 'Golden Rules' of Software Engineering in Bubble

Added two tips!

  • From @AirDev: When running API workflows in Bubble, the number of items that the workflow has to execute upon has a greater impact on performance than the size of each item. (source)
  • From @djtochner: When creating a looping workflow, make sure you have a safety switch/condition that will shut the workflow down so it doesn’t suck all of your capacity. (source)

I’d like to contribute with this naming convention:

I use this naming convention (copied from one of my other replies):

  • Data types should be singular and capitalised (Post, Entry, Order rather than posts, Entries, or All Orders for example). Multiple words should be, well, multiple words e.g Concert Ticket (I know some just won’t like having spaces in DB field names though). This helps you differentiate Things from fields.

  • Where a field references another data type or option set (e.g Variant has a field of type Product), name that field the name of the type exactly. So in this case the name should be Product and type also Product. If it’s something like ‘favouritePost’, I would write this as ‘favouritePost’ This helps you easily identify what a field refers to and the type of that field.

  • In relation to the above, don’t save foreign types as fields like ‘ProductID’. ‘ProductID’ just implies it’s a string (a text field) when actually it’s a Product.

  • Where a field is a basic data field (i.e text, yes/no, number etc where it doesn’t reference a type/option), name it lowercase with extra words capitalised. e.g dateOfBirth, or fullName. This helps you know that a certain field is just a basic field rather than referencing other data in the DB.

  • I name option sets in the same way as I name Data types but wouldn’t have a problem if option sets were prefixed with OS or a symbol to show they’re option sets.

1 Like

If you find yourself frequently needing to dynamically specify which field to modify on a type, you probably need a new data type where that field is an option set.

For example, for order statuses, instead of having fields ‘dateOrdered, dateAccepted, datePacked, dateShipped, dateDelivered’, have a List of Order Statuses where Order Status contains the date and the status (Ordered, Accepted, Packed etc option set). The exception might be dateOrdered which should also be kept on the Order data type for efficiency purposes.


Great one! Added :blush:

It is crucial not to nest reusable elements within each other, especially multiple or many layers deep. This practice will severely limit site performance and cause crashing, especially with bigger apps.


Anecdotally I have never experienced this and using nested reuseables is virtually a requirement for single page apps unless you want using the editor to feel so slow it’s like the Bubble servers are on the Moon.


I have a larger app with millions of WFU/month and I can say for certainty that it can cause severe limitations both in live mode and in the editor if you nest them. During my initial iteration I had dozens nested at 3-4 levels deep and my app was completely unusable. A bubble support person reviewed my app and told me about this practice and I quickly restructured it and it was literally 800x faster (per google developer console). Bubble had told me they resolved this back in 2022 and I started going back to using a lot of nested elements (because it can be much easier) but I experienced similar trouble (although not quite as bad as it was pre 2022, so I do think they made it better).

I again un-nested the reusables and I am off to the races again.

Instead I built a page to store a lot of my reusable pop-ups to route to and then use a “redirect=curent_url” url parameter to route the user back to where they are. It works well.

1 Like

The support agent is only referring to editor performance. I can’t see a technical reason reuseables would slow down performance in run mode, but if I’m happy to be corrected (well, not happy that it slows down performance but you know what I mean…)

I’d almost bet nested reusables aren’t the issue, rather an over use of nested popups. All Popups load on page load, you typically only want to use popups for CRUD operations that don’t require large data searches rather have a single item passed to them.

Many times people use popups to store variables to “pre load” data and it destroys performance especially when many popups are expected to be loaded.


I have a few features with nested repeating groups, 3 levels. It depends on what data your loading into them, how much and how you’re doing it. Reusable elements improve nested repeating group performance a lot too.

Even a single RG can affect your page speed if not used right. If an RG (data source) and/or each of it’s cells has to do intensive operations, naturally it’s going to affect your pages’ performance since Bubble needs to calculate how the list renders.

If your nested RGs are processing simple data like text and numbers or evaluating simple/fast operators like count or regex then it won’t affect affect page performance much.

My apps don’t accumulate millions of WUs a month (neither would I brag about it if they did). I do a lot of client side processing for huge lists and/or use processed datatypes to split/lighten load at different parts of my UX.


Sure does

Great value for Bubblers

1 Like

Anything not protected by privacy rules is public, even if you don’t show it in your app.

Another common thing I see: Current user’s logged in is not a sufficient privacy rule if anyone can create an account.

1 Like

Great ones! Added :blush:

These are great points, looks like I’ll be doing an audit on a few of my apps based on these. Would be pretty awesome to have these tips in some form of wiki-esque site, possibly with up/downvotes and comments… could be a fun project.

1 Like

why not just create a database view and use that in the search function instead?

He’s referring to a new data type, not just a database view.

The higher the number of fields a data type has, the heavier it gets.

The heavier the data type, the slower it loads when you search for it, and not to mention the insane WU you would incur.

I get that, but I thought creating a database view solves the problem without the need to create (and maintain!) a new data type altogether. Let’s say that you have a data type with 50 attributes. Then you create a view with 5 of them, which you then do a search for in your app. This makes it faster and lighter.

Does it not work like that?

No it doesn’t…

Creating a new database view with X fields of a datatype doesn’t make it lighter.

You’d still be searching for the data type itself, not the view.

Edit: Even if you only show 5 fields in say, a repeating group, the other 45 is still being loaded. Unless of course if you have privacy rules set for those other 45 fields