Bubble Docs
  • Introduction
  • New? Start Here
  • What is Bubble?
  • The Glossary
  • User manual
    • Getting started
      • What is Bubble?
      • Building for...
        • Web
        • Native iOS and Android
          • Mobile app quick start guide
          • What is a native mobile app?
          • Native mobile vs. web development
          • Differences in native and web elements
          • Native mobile app terminology
      • Building your first app
        • Planning features
        • Database structure
        • Design and UX
        • eCommerce and payments
          • Shopping cart
          • Checkout page
          • One-time payments
          • Subscriptions
          • Marketplace
      • Creating and managing apps
      • The Bubble editor
        • Tabs and sections
          • Design tab
            • The element tree
            • The property editor
          • Workflow tab
          • Data tab
          • Styles tab
          • Plugins tab
          • Settings tab
            • Application settings
              • Custom headers/body
              • Visual settings
              • Social media sharing
              • Translating your app
              • Email settings
              • Collaboration
            • Custom domain and DNS
          • Logs tab
        • Tools
          • Key features
          • The search tool
          • The Issue Checker
          • The element tree
          • The element property editor
          • The debugger
          • Notes
        • Previewing your app
      • Transitioning to Bubble from...
        • JavaScript
        • HTML and CSS
        • SQL
    • Design
      • Elements
        • Web app
          • The page
          • Containers
            • Groups
            • Repeating groups
            • Table elements
            • Popups
            • Floating groups
            • Group focus
          • Visual elements
          • Input forms
            • Text and numbers
            • Dates and time
            • File uploads
            • Selection controls
        • iOS and Android app
          • The view
          • Containers
          • Visual elements
          • Input forms
          • Mobile reusable elements
        • The element hierarchy
          • The element tree
        • Reusable Elements
      • Styling
        • Color variables
        • Font variables
        • Styles
        • Custom Fonts
      • Responsive design
        • Building responsive pages
        • Legacy articles
          • The Basics (Legacy)
          • Building Responsive Pages (Legacy)
          • Migrating Legacy Pages
          • Tips When Designing (Legacy)
      • Templates
      • The Component Library
      • Importing from Figma
    • Data
      • The database
        • Data types and fields
        • Creating, saving and deleting data
        • Finding data
        • Displaying data
        • Protecting data with privacy rules
        • The database editor
        • Export/import data
          • Exporting data
          • Importing data (CSV)
        • Working with location data
        • Using Algolia
        • Database structure by app type
          • Marketplace Apps
          • Directory & Listings Apps
          • Social Network Apps
          • SaaS Apps
          • Project Management Apps
          • CRM Apps
          • Professional Services Apps
          • On-demand Apps
          • Documentation/ CMS Apps
          • Applicant Tracking System (ATS) Apps
          • Portfolio Apps
          • Gallery Apps
          • Online Store / Ecommerce Apps
          • Blog Apps
          • Messaging App
          • Dashboards
          • Building Block Apps
          • Bubble as a backend
      • Files
      • Images
      • Static data
        • App texts (translations)
        • Option sets
      • Temporary data
        • Custom states
        • URL parameters
      • User accounts
        • Authentication plugins
          • Facebook plugin
          • Fitbit plugin
          • Google plugin
          • Instagram plugin
          • LinkedIn plugin
          • Pinterest plugin
          • Slack plugin
          • Wistia plugin
          • YouTube plugin
        • Cookies set by Bubble
      • Time, dates and time zones
    • Logic
      • The frontend and backend
      • Workflows
        • Events
          • Frontend events
            • Recurring workflows
            • Custom events
          • Backend events
            • Database trigger events
        • Actions
        • API Workflows
      • Dynamic expressions
      • Conditions
      • Navigation
        • Single-page applications (SPA)
        • Multi-page applications
        • Page slugs
      • Device resources
        • Location services
        • Camera/photo library
    • Workload
      • Understanding workload
        • Activity types
        • The workload calculation
        • Client-side and server-side processing
      • Tracking workload
        • Measuring
          • Using App Metrics
        • Monitoring
          • Workload notifications
          • Infinite recursion protection
      • Optimizing workload
        • Optimization framework
        • Optimization checklist
          • Page load
          • Searches
          • Workflows and actions
          • Backend workflows
        • Agency showcases
          • Minimum Studio
          • Neam
          • Support Dept
    • Security
      • Bubble's security features
      • Planning app security
      • Client-side and server-side
      • Bubble account security
      • App security
      • Page security
      • Database security
      • API security
        • API Connector security
        • Data API security
        • Workflow API security
      • Flusk
        • Overview
        • Flusk plan features
        • Getting started with Flusk
        • Flusk security tools
          • The Issues Explorer
          • Issue details
          • Tools and settings
            • Pages rating
            • Database rating
        • Flusk FAQ
      • Cookies
      • Security checklist
    • Previewing your app
      • Previewing a web app
      • Previewing a mobile app
    • Publishing your app
      • Web app
      • Native mobile app
        • Global native mobile settings
        • iOS App Store
        • Google Play Store
        • Publishing FAQ
    • AI
      • Generate apps with AI
        • About AI app generation
      • AI page designer
      • Connect to AI agents
    • Maintenance
      • Collaborators
      • Version control
        • Best practices: Version control
        • Transitioning from the legacy version control
        • Terminology: Version control
        • Version Control (legacy)
      • Commenting
      • Database maintenance
        • Copying the database
        • Restoring database backups
        • Bulk operations
          • Bulk operation methods compared
        • Wiping change history
      • Performance
        • Hard limits
        • Capacity Usage (legacy)
        • Notes on queries
      • SEO
        • Introduction to SEO
        • SEO: App
        • SEO: Page
      • Testing and debugging
        • Introduction to testing and debugging
        • The debugger
        • The server logs
        • Supported browsers
      • API workflow scheduler
    • Integrations
      • API
        • Introduction to APIs
          • What is a RESTful API?
        • The Bubble API
          • Bubble API terminology
          • Authentication
            • How to authenticate
            • No authentication
            • As a User
            • As an admin
          • The Data API
            • Data API Privacy Rules
            • Data API endpoints
            • Data API requests
          • The Workflow API
            • Workflow API privacy rules
            • Workflow API endpoints
            • API workflows
              • Creating API workflows
              • Scheduling API workflows
              • Recursive API workflows
              • API Workflow Scheduler
              • Case: Stripe notifications
        • The API Connector
          • Authentication
          • API Connector security
          • API guides
            • OpenAI
              • Authentication
              • Calls
                • ChatGPT
                  • Chat
            • Google Translate
              • How to setup Google API keys
          • Streaming API
        • API security
        • Plugins that connect to APIs
        • API Glossary
      • Plugins
        • What Plugins Can Do
        • Installing and using Plugins
        • Authentication plugins
        • Special Plugins
      • SQL Database Connector
      • Bubble App Connector
      • WorkOS
        • WorkOS SSO
        • WorkOS API
    • Infrastructure
      • Sub-apps
      • Bubble release tiers
      • Hosting and scaling
        • How Bubble hosting works
        • Scaling with Bubble
        • CDN (Cloudflare)
        • Bubble app names
        • Domain and DNS
      • Compliance
        • GDPR
        • SOC 2 Type II
        • HIPAA
        • Other frameworks and standards
    • Bubble for Enterprise
      • Hosting and infrastructure
        • Dedicated instance
          • The Dedicated editor experience
          • Technical specs
          • Main cluster dependencies
          • Customizable options
          • Migration process
            • Pre-migration
            • During migration
            • Post-migration
      • Security and compliance
        • Single sign-on (SSO)
        • GDPR
        • SOC 2 Type II
        • HIPAA
        • Other frameworks
        • Bubble's security features
      • Admin and collaboration
      • Priority support
      • Billing and Payment Guideline for Dedicated Instances
  • Core Reference
    • Using the core reference
    • Bubble's Interface
      • Design tab
      • Design tab (Legacy)
      • Workflow tab
      • Data tab
      • Styles tab
      • Styles tab (Legacy)
      • Plugins tab
      • Settings tab
      • Logs tab
      • Template tab
      • Toolbar
      • Top and context menu options
      • Deployment and version control
        • Deployment & Version Control Dropdown (legacy)
      • Notes
    • Elements
      • Native mobile elements
        • View element
        • List component
      • General properties
      • General properties (Legacy)
      • Styling properties
      • Styling Properties (Legacy)
      • Responsive Properties
      • Responsive Properties (Legacy)
      • Conditional formatting
      • States
      • Page Element
        • Page Element (Legacy)
      • Visual Elements
      • Containers
      • Container Layout Types
      • Containers (Legacy)
      • Input Forms
      • Reusable Elements
      • Element Templates (legacy)
    • Workflows
    • Events
      • General events
      • Element events
      • Custom events
      • Recurring event
      • Database trigger event
    • Actions
      • Account
      • Navigation
      • Data (things)
      • Email
      • Element
      • Custom
    • On-device resources
    • Data
      • Data Sources
      • Operators and comparisons
      • Search
      • Privacy
    • Styles
    • API
      • The Bubble API
        • The Data API
          • Authentication
          • Data API endpoints
          • Data API requests
        • The Workflow API
      • The API Connector
        • Authentication
        • Adding calls
    • Bubble-made Plugins
      • AddtoAny Share Buttons
      • Airtable
      • API Connector
      • Blockspring
      • Box
      • Braintree
      • Bubble App Connector
      • Chart.js
      • Circle Music Player
      • Draggable Elements
      • Dropzone
      • Facebook
      • Fitbit
      • Full Calendar
      • Google
      • Google Analytics
      • Google Optimize
      • Google Places
      • Ionic Elements
      • iTunes
      • Slidebar Menu
      • LinkedIn
      • Localize Translation
      • Mixpanel
      • Mouse & Keyboard Interactions
      • Multiselect Dropdown
      • Progress Bar
      • Rich Text Editor
      • Rich Text Editor (Legacy)
      • Screenshotlayer
      • SelectPDF
      • Slack
      • Segment
      • Slick Slideshow
      • SQL Database Connector
      • Star Rating
      • Stripe
      • Tinder-like Element
      • Twitter
      • YouTube
      • Zapier
    • Application Settings
      • App plan
      • General
      • Domain / email
      • Languages
      • SEO / metatags
      • API
      • Collaboration
      • Sub-apps
      • Versions
  • Account & Marketplace
    • Account and billing
      • Pricing and plans
        • Plans and billing
        • Billing cycle
        • FAQ: Pricing and Workload
      • Account Management
      • Building Apps for Others
      • Selling on the Marketplace
      • Plans & Billing (legacy)
    • Official Bubble Certification
      • Hiring certified developers
    • Building Plugins
      • The Plugin Editor
      • General Settings
      • Updating to Plugin API v4
      • Adding API Connections
      • Building Elements
      • Building Actions
      • Loading Data
      • Publishing and versioning
      • Github Integration
    • Building Templates
    • Application and data ownership
    • Marketplace policies
    • Bug reports
  • Vulnerability Disclosure Policy
  • Beta features
    • About the Beta features section
    • Native mobile apps
Powered by GitBook
On this page
  • General principles & tips about performance
  • What happens on page load?
  • Working with soft limits
  • Hard vs soft limits
  • Timeouts
  • Predicting and planning for limitations
  • Throttling and how it may affect timeouts
  • Known soft limits
  • SVG image size
  • Searches with the :advanced constraint
  • Additional notes about performance
  • Capacity
  • What about dedicated instances?
  • In closing

Was this helpful?

  1. User manual
  2. Maintenance

Performance

The Bubble team is constantly looking to optimize scalability and performance. This means improvements to both the Bubble platform to handle all the thousands of Bubble apps (our scalability and performance), as well as to the platform so that Bubble apps provide a good experience for their end-users.

Performance and scaling of a Bubble app are heavily impacted by how the app is built. This page will give an overview of app performance and scalability as well as offer some concrete tips.

General principles & tips about performance

  • The less data being fetched, the faster the performance - a page often needs to fetch some data on page load; a page that fetches 100 things on page load will load faster than a page that fetches 1 million data items; similarly, fetching simple data types like numbers will be faster than fetching MBs of data

  • Similarly, having many small, simple pages will be faster than having fewer, complex pages

  • Keep any sorting or filtering as close to the original search as possible - Bubble already optimizes database queries in many ways, but performing a sort or filter at the database level is very efficient. This means that queries that apply :sort or :filter to them will tend to be more efficient than queries with sorting or filtering after some other kind of manipulation of the results (example: doing search:count will be more efficient than search:group by:count)

  • Using advanced filters can slow queries down - An underlying principle is that if a filter (or sort) can be done "on the database", it will be faster than a filter (or sort) that Bubble has to do after retrieving an initial set of data from the database. Which filters are done on the database vs. not? Filters which show up in the Search palette (the additional sidebar which slides out when you click "Do a search for") are done on the database and are thus are generally fast. Filters which are applied with :filter are generally "advanced" filters that are generally slower.

  • Chained queries run in series, not in parallel - With Bubble it's possible to use the results of one search as the constraints of another search, and so on. These searches run in series, not in parallel, so if the first search returns a lot of data, that will slow the second search down, and so on

  • Bubble already does a lot of performance optimization - Bubble tries to run queries on the database, resize images on the server, tell the browser to cache Javascript, etc. as appropriate. If you're running a query that feels relatively simple and retrieves a relatively small amount of data that's running very slowly, check if there is some optimization that can be done to the app's data hierarchy or queries, based on some of the guidance here

  • In general, the simpler way to express a query is faster - Not always true but a good rule of thumb. Bubble is constantly working on database optimizations for the most common patterns

  • Avoid modifying data on every page load - Changing element states is more performant than making additional database calls to accomplish the same behavior

  • Try moving expensive calculations to behind-the-scenes scheduled workflows - A scheduled workflow can run the heavy query then save the result somewhere to use later; this is more performant than running the heavy query on a page load

  • Use the "Make changes to a list of X" workflow action cautiously - This action is great when making a quick change to a short list of things, but as the number in the list grows, it quickly raises the risk of the workflow timing out. If you're experiencing timeouts with this action, consider instead "Schedule API Workflow on a list", which is more performant because it takes the list and schedules an API Workflow to run on each item of the list, separately (i.e. lowering the risk of a timeout)

Watch out!

Your Bubble app's database is very flexible and powerful. It can store a lot - but if you try to store too much data in one field, it can lead to performance issues relating to that field. For example, if you have a Blog data type with a field for Contents, this should be able to handle blog posts just fine. But, if you try to stuff all the contents from Wikipedia into that one field, it probably will not work as well! More realistically, if you try to store a base64-encoded image (which is a lot of text) in a text field, this can lead to slower performance and unexpected behavior.

What happens on page load?

Here is a rough sequence of events of what happens when Bubble loads a page:

  1. Bubble sends the code for all the elements (visible and invisible)

  2. Bubble draws all the visible elements on the page

  3. Bubble fetches all the dynamic data needed for the visible elements

This means:

  • Invisible elements aren't drawn until they get displayed later...

  • ...unless a visible item refers to an invisible item's data source. (Note that using one visible element to cover another visible one does not make the latter one "invisible" in this context!)

  • For page load speed, the number of elements is a bigger factor than the type of elements

All the element types are fairly similar to each other in terms of performance, with two exceptions:

    1. A repeating group with 10 cells each with 2 elements is faster than 20 separate elements, but slower than 3 elements

    2. A nested repeating group has a multiplicative effect on the number of elements!

  1. Plugins have their code included on each page load regardless if it's used. This isn't as big a performance impact because Bubble won't render the plugin if it's not used, but in general, it's a good idea to uninstall plugins that the app isn't using

Working with soft limits

Hard vs soft limits

Before we look at how different limitations might affect your project, we'd like to briefly cover the concept of hard and soft limits:

Soft limits are flexible boundaries that can be exceeded in but may impact performance or stability. Soft limits are influenced by factors such as the structure of your application and your pricing plan. For instance, a large volume of database records with substantial data can result in slower search performance.

Hard limits are fixed boundaries that cannot be exceeded. Some hard limits can be increased by upgrading to higher pricing plans, and others can be circumvented through thoughtful app design and optimization, but as a developer you should be aware of them and how they might affect your project.

You can read more about hard limits in our dedicated article on the subject:

Timeouts

Timeouts can happen when a specific action takes too long to complete and is terminated by the system. They are used to prevent a single request or app from monopolizing server resources, to make sure that all applications on our shared servers remain responsive and performant.

Predicting and planning for limitations

As with any database system, slowdowns, timeouts and errors when applying pressure on the Bubble server can be challenging to predict and plan for and depend a great deal on how your app is designed and the volume of data you are working on.

Timeouts are rare, but can be challenging to predict and can lead to data loss and other consequences as a result of a process being terminated before it has finished.

While we can document the hard limits you might encounter, soft limits are more complex as they can vary greatly depending on what your app is doing. To minimize the risk of slowdowns and timeouts, we recommend you break up complex processes into smaller chunks.

Throttling and how it may affect timeouts

If your app spends its near-maximum allotted capacity for some time (closing in one one minute), your app may be throttled to keep it running without exceeding capacity. This can lead to a negative feedback loop where workflows are slowed down and exceed their hard timeout limit as a result. Therefore, timeouts may appear to be unpredictable, as a process may complete successfully on one occasion but time out on another.

We recommend thinking holistically about your app's total capacity and keep in mind that simultaneous process can affect each other. If you can, try to move heavy processes to times when your app is less active (for example at times where you have fewer active users)

Known soft limits

SVG image size

SVG images are stored in XML code which is parsed by your browser to render a vector-based graphic that can be scaled up or down without losing resolution. This is different from raster images, such as JPEG or PNG files, that can become pixelated when scaled beyond their original size.

This makes SVG files very useful in many situations, but we recommend a soft limit of 1 Mb for SVG files to avoid the local device slowing down when processing the file.

Searches with the :advanced constraint

Searches that use the :advanced operator can be more taxing on the server. While there's not a hard limit on what you can search through, we generally don't recommend using this constraint on more than 10,000 things.

Additional notes about performance

The power of reuse:

  • If a page has the same search in more than one place, Bubble will automatically combine them to run the query once

  • Leveraging Styles helps improve performance

  • The first few times you run a particularly heavy search might be a bit slower than future runs, because after Bubble sees a heavy query run a few times, Bubble builds an index that should massively speed up the search in the future (building the index could take up to an hour or so)

X vs Y:

  • An action that changes a dozen fields is more efficient than a dozen actions that change one field

  • Changing a list of things is fast for relatively small lists, but for bigger lists, an API workflow will be more scalable since it doesn't run the risk of timing out the workflow

  • When changing a (large) list, recursively calling an API workflow for subsequent items on the list is more scalable, though a bit slower, than running the API workflow on the entire list at once

  • Navigating to a new page via a link element is generally a little bit faster, because workflow actions that navigate will wait on other workflows to save data before changing the page

  • For situations where data type A has connections to multiple Bs (e.g. posts having categories but only one category per post; A = category, B = post), having a field on B that references the A it belongs to is generally better. Having a field on A that lists out all the Bs that belong to it is not going to work as well when that list can get very long

  • For API workflows, the number of items the workflow has to act upon is a bigger impact on performance than the size of each item

Capacity

In non-technical terms, "capacity" measures how much "stuff" your app can do in a given period of time. A user coming to your website uses a bit of capacity; having hordes of users coming to your website uses much more capacity. Calling the database uses capacity; performing lots of heavy database queries uses much more capacity. Running certain workflows (the ones that happen on the server) uses capacity, and similarly calling an app's APIs uses capacity.

Throughout Bubble, there are references to "units" of capacity. A "unit" is a weighted measure of different scarce resources that Bubble's systems use; it includes factors like server CPU time, database CPU time, other backend systems, and more. The exact formula for a "unit" will change over time as Bubble adds, removes or improves backend systems; one of Bubble's goals is to improve the amount of user-facing performance that a unit of capacity delivers.

There's a slight twist to this. Capacity can be compared to how many checkout lines there are at a grocery store. If the store adds more lines, it can handle more customers checking out at the same time. But, if a customer comes along with a cart of hundreds of items, that customer will still take up a whole checkout line for a while; also, having more checkout lines doesn't mean that resource-intensive customer will finish faster. Similarly, having more capacity won't make a very complex database query run that much faster - it's like that one customer checking out with a lot of items in their cart. (There is a caveat to this: if Bubble detects that a large query will eat up all of an app's capacity, Bubble will slow down that query to try to maintain a reasonable user experience for the rest of the app. Thus, in certain situations, adding capacity might make a large query run faster.)

Users can see how much capacity their apps are using by going to Logs on the left-side nav. The first chart shows how much time the app has hit its maximum capacity; the second chart shows how much capacity has been used by the app relative to its maximum capacity. Further down on the page is the server capacity usage details chart, which shows the breakdown of capacity used by different parts of the app within the past 24 hours. If an app is slow and is hitting capacity limits, purchasing reserved additional capacity may help.

Note: Our server logging provider, AppOptics, has limits on the metric we use for the Maximum Capacity charts. Very high-activity Bubble apps may hit this limit when trying to query the logs for a long time period (i.e. 30 days). If this happens in your app, consider setting the chart date range to a shorter duration (i.e. 7 days).

What about dedicated instances?

Dedicated instances can help with performance in three primary ways:

  1. Geography - a dedicated instance can be located geographically closer to your users, which helps with the performance of large static assets

  2. Heavy data operations - these can be substantially faster on a dedicated instance

  3. Stability - with dedicated instances you can test an app on the main Bubble cluster before upgrading the dedicated instance; this can be useful for ensuring an app's stability with a new version of Bubble, as well as eliminate the risk of a Bubble-wide outage

In closing

Last updated 1 year ago

Was this helpful?

Repeating groups load different amounts of data depending on the Layout Style property; notes on performance of the different choices are in the . Note also that the more elements there are in each cell of the repeating group, the more time it takes to render the page

Article:

On certain Bubble (namely Free and Personal), the app will have "Basic" server capacity, which means it's sharing the same computing resources with all other Bubble apps of these tiers. When an app is upgraded to the "Professional" and "Production" tiers, the app gets dedicated or "reserved" units of capacity which are reserved for that app. When capacity is exceeded, the app is rate-limited; again in non-technical terms, it means the app won't be able to do as much "stuff" in a given period of time, and users' requests on the app will effectively be slowed down. Thus, having more capacity generally means that the app can do more "stuff" if a lot of "stuff" is going on.

If you're interested in hosting your app on a Dedicated instance of Bubble and want to learn more, please contact our sales team .

At the end of the day, the above are general guidelines that are meant to provide some transparency into factors impacting performance. However, these are only guidelines; if performance is critical in a particular case for your app, try testing different approaches empirically to see what's faster!

Reference
Bubble's hard limits
pricing tiers
here