Our Bubble Performance Engineering Playbook
A slow Bubble app is not a Bubble problem — it is an architecture problem. Four root causes, six anti-patterns with their exact performance impact, and our four-step audit process that consistently achieves sub-one-second dashboard load times.
A Slow Bubble App Is Not a Bubble Problem — It Is an Architecture Problem
Every slow Bubble app we have been asked to optimise has the same root causes: :filtered by instead of search constraints, live count queries on dashboard render, unpaginated repeating groups, and missing denormalisation. These are not platform limitations. They are architectural decisions made without understanding their performance consequences. Our performance engineering playbook addresses each one systematically.
The Four Root Causes of Slow Bubble Apps
| Anti-Pattern | What Happens | Performance Impact | Our Fix |
|---|---|---|---|
| :filtered by on any search | Loads ALL records to browser; filters in JavaScript | 50-100x slower than a constraint; gets worse as data grows | Replace with search constraints. Zero exceptions. |
| Live counts on dashboard render | Each count triggers a full table scan per page load | 10-20 queries per dashboard page; 8+ second loads | Denormalise all counts; read pre-calculated numbers |
| Unpaginated repeating groups | Browser renders 500+ DOM nodes; scrolling freezes | 3-10x slower rendering; memory pressure on mobile | Paginate all RGs to 20 items; implement lazy loading |
| Deep relational chains in RG cells | N queries per row (one per relationship hop) | N rows × N hops = exponential query count | Denormalise key fields onto primary type; flatten the chain |
| Static data in data types | DB query for every status dropdown on every render | 5-10 unnecessary queries per page load | Convert to Option Sets: zero DB queries, instant render |
| Multiple sequential API calls on render | Each call adds 200-1500ms; blocks page render | 2-8 seconds of blocking API calls per page load | Move to backend workflows; preload via page load state |
How We Audit and Fix a Slow Bubble App
Instrument the current performance
Before touching anything, we document baseline load times for every dashboard page using browser developer tools. We record which searches are being performed on each page load and note the record counts each search is processing. This baseline tells us where to focus effort and confirms improvement after each fix.
Audit every search expression
We review every ‘Search for’ expression in every workflow and every element data source. We identify every :filtered by and mark it for replacement. We identify every search missing a workspace constraint and flag it for both performance and security reasons. This audit typically takes 2-4 hours for a medium-complexity app.
Implement denormalised counters
For every count displayed on a dashboard or used in a plan limit check, we add a counter field to the Workspace record. We update this counter in every workflow that creates, deletes, or changes the counted records. We update the element data source to read from the counter instead of performing a count search.
Establish pre-loading patterns
For pages that display multiple data items, we implement a page load workflow that fetches all needed data in a single batch and stores it in page-level custom states. Elements read from states rather than performing individual searches. Dashboard render time typically drops 60-80% from this single change.
Work With a Bubble Architect
Most developers build Bubble apps. We architect them. Data models designed for scale, multi-tenant security built from day one, Stripe billing that never fails, and workflows engineered for performance. This is what a Bubble Architect delivers.
