Bubble.io Performance Optimization: 7 Patterns That Make Your App Fast
Slow Bubble apps are almost never Bubble’s fault. They are the builder’s fault. Seven specific anti-patterns cause 90% of all Bubble performance problems — and seven specific counter-patterns prevent every one of them.
Why Bubble Apps Get Slow — And Why It’s Almost Always the Builder
Bubble fetches data from a PostgreSQL database, runs it through a server-side engine, and sends it to the browser. When this feels slow, it is almost always because too much data is being fetched (wrong query approach), it is being filtered in the browser instead of the database (the :filtered by anti-pattern), or it is being fetched in the wrong place at the wrong time (missing caching, repeated count queries). Fix these three root causes and you fix 90% of Bubble performance problems.
The 7 Patterns That Separate Fast Bubble Apps From Slow Ones
Pattern 1 — Never Use :filtered by in Searches
:filtered by status = “Active”
// Fetches ALL projects from DB
// Filters in the browser
// Gets slower as data grows
status = “Active” ← constraint
// Runs as DB WHERE clause
// Returns only matching rows
// Fast at any data volume
Pattern 2 — Paginate All Large Lists
A repeating group trying to render 5,000 records will freeze the browser. Pagination with a page size of 15–25 ensures every list renders in milliseconds regardless of total data size. Use “Load More” or page number navigation — never unlimited lists in production apps.
Type of content: Project
Data source: Search for Projects [constraints] :paginate(page: current_page, items per page: 20)
Load more button: current_page = current_page + 1
Pattern 3 — Use Option Sets for All Static Data
If you create a “Status” data type with five records (Active, Paused, Cancelled, Trialing, Expired), Bubble fires a database query to load those five records every time a dropdown or condition references them. An Option Set fires zero queries — the values are compiled into the app. For any fixed list, Option Set is always the correct choice.
Pattern 4 — Denormalise Dashboard Counts
Projects count: Search for Projects[workspace=current]:count
Tasks count: Search for Tasks[workspace=current]:count
// ✅ Store counts on Workspace record — zero queries at render
Workspace: project_count (number), task_count (number)
On Create Project: Workspace’s project_count = project_count + 1
Dashboard reads: Current User’s current_workspace’s project_count
Pattern 5 — Always Constrain Searches to Workspace
Every search without a workspace constraint scans your entire dataset regardless of how many tenants you have. As your app grows from 10 to 1,000 workspaces, unconstrained searches grow 100× slower. Every single search in every workflow and page must have workspace = Current User’s current_workspace as the first constraint — without exception.
Pattern 6 — Avoid Deep Relational Chains
Each → fires a new database query. In a 20-row repeating group this is 80 separate DB calls on every render.
Pattern 7 — Soft Delete, Never Hard Delete
Add is_deleted (yes/no) to every data type. Set it to yes instead of destroying the record. Add is_deleted = no to every search. Benefits: undo capability, audit trails, data recovery, and compliance with data retention requirements. Hard-deleting records in a SaaS is a practice that always creates problems you cannot undo.
Performance Audit: Run This Before Launch
-
✓
Zero :filtered by expressions — all filtering uses search constraints
-
✓
All repeating groups have a maximum page size of 15–25 records
-
✓
All static data (statuses, roles, categories) uses Option Sets, not data types
-
✓
Dashboard counts stored as denormalised fields on Workspace, not queried at render
-
✓
Every search has workspace = current_workspace as first constraint
-
✓
No relational chains deeper than two levels in repeating group cells
-
✓
Every data type has is_deleted (yes/no) field
-
✓
Bubble app on Growth plan or above for production (dedicated server)
Is Your Bubble App Slower Than It Should Be?
We audit and optimise Bubble apps for performance. Most issues are fixable in a single session.
