Client-side and server-side processing
In the Infrastructure section of the manual, we explain the differences between client-side and server-side processes. Running a Bubble app is a collaborative effort between the user's device (computer, tablet, or phone) and the Bubble server. Although more than one server can be involved, this article focuses on these two devices and how they affect workload management.
Workload is essentially the aggregated metric indicating how much work the server does to keep your app running. While server-side operations contribute to this workload, client-side workflows, such as animating an element, do not add to the server’s workload.
Still, essential client-side operations can sometimes depend on the server to function properly. For example, loading a page requires the server to compile and send data to the user’s device, even if the page rendering happens client-side. Likewise, animating an element is a client-side action, but a condition or other actions within the same workflow may still require server communication, and showing a previously hidden repeating group can lead to its data source fetching data from the database.
In this article, we'll explore which workflows are performed server-side and client-side, and the design decisions that can force Bubble to include server-side operations, even in workflows that are typically client-side.
The difference between client-side and server-side operations
While it may not cover every scenario, asking the following overarching questions can often reveal whether an operation involves the server:
Does the operation require accessing or modifying data stored in the database?
Server-side
Involves database operations
Is the operation using or calling an API?
Server-side
APIs are routed through the server
Is the operation related to user authentication or session management?
Server-side
Involves security and session verification
Does the operation involve complex calculations or data processing?
Server-side
Leverages server resources for processing
Is the operation dependent on real-time user interactions, like displaying or hiding elements?
Client-side
Handled by the user’s device
Going more into detail, we can also divide typical processes into client-side and server-side. The list below is not comprehensive, but illustrates some typical operations that would include either the client or the server. In principle, all operations that involve the database, files, backend workflows and external APIs will need to involve the Bubble server in some way.
Set a custom state value
User authentication (login/signup)
Element visibility (show/hide)
Database searches and queries
Form input handling
Sending emails (confirmation, reset)
Animations and transitions
Data creation, modification, and deletion
Scrolling to elements
External API calls
Client-side calculations
File uploads and deletions
Displaying data
Scheduled workflows
Updating element states
Managing user sessions
Resetting input fields
Assigning temporary passwords
Showing alerts and messages
Processing recurring events
It's important to understand that even if an operation can be done client-side, its settings and properties might still require server involvement.
For example, the "Display data" action is technically client-side, but if you're displaying data from the database in a container element like a group, that data must be loaded from the server. Conversely, if you use "Display data" to load a static number, it can be handled entirely client-side.
Additionally, the purpose of this guide is to help you understand how workload calculation is affected by client-side and server-side operations—not to suggest that you should always avoid server operations. All Bubble apps need to connect to the server to function, and there are security, efficiency, and functionality considerations when trying to move tasks away from the server.
Below, we’ll start breaking down how workflows and elements involve the server when needed.
Workflows
A workflow can consist of many pieces. To understand what happens where, we need to divide the workflow into separate categories that can potentially spend workload. All backend workflows are performed server-side, but frontend workflows can be executed server-side or client-side.
A workflow consists of components like the below tree:
The event
Actions
Dynamic expressions:
Conditions on the workflow
Conditions on separate actions
Dynamic expressions that are part of an action
Let's go over each component in more detail.
Events
Every workflow in Bubble is triggered by an event, such as a button being clicked. When Bubble identifies an event happening, it will check any additional conditions on the event, and proceed to run the actions inside.
Events table
User is logged in
Server-side
Authentication is managed on the server
User is logged out
Server-side
Session management is handled on the server
Page is loaded
Both
The page is loaded event can be triggered before the page loads, but can also be triggered on the client, depending on actions and conditions
Do every 5 seconds
Client-side
Timer events are handled client-side
Do when condition is true
Depends
It depends on the dynamic expression
An unhandled error occurs
Client-side
Errors are detected and managed locally. An error can be the result of a server-side action.
An element is clicked
Client-side
Click events are handled client-side
An input's value is changed
Client-side
Input changes are managed client-side
An element has an error running a workflow
Client-side
Element errors are detected locally. An error can be the result of a server-side action.
Custom event (on page)
Client-side
Custom events on the page are handled locally. Actions and dynamic expressions can still be processed server-side.
Custom event (Backend)
Server-side
Backend events are always processed server-side.
API workflow
Server-side
Backend events are always processed server-side.
Recurring workflow
Server-side
Backend events are always processed server-side.
Database trigger event
Server-side
Backend events are always processed server-side.
Actions
Inside each workflow, there are one or more actions. When an event is triggered, Bubble checks the conditions for each action and executes them if the conditions are met. These actions can perform server-side operations (such as writing to the database) or client-side operations (such as hiding or showing an element).
Let's review each action to determine if it's performed client-side or server-side. Note the following when reading the table:
The table only considers the cost of the action itself, not any additional workload consumption the action may lead to.
Example 1: triggering a page refresh doesn't consume workload, but loading the new page does (this is not part of the action).
Example 2: Similarly, triggering a custom event is handled client-side, but actions within that custom workflow may still consume workload.
Example 3: Setting a custom state is a client-side operation, but it may involve fetching data from the database.
Any extra workload from dynamic expressions in fields or conditions is not considered in this table.
Many server-side operations still include client-side processing, which means this list shouldn’t be read as black and white. We’ve marked them as server-side, since client-side doesn’t affect your workload.
Actions table
Sign the user up
Server-side
Involves user data processing and database operations
Log the user in
Server-side
Authentication requires server verification
Signup/login with a social network
Server-side
Uses external API for authentication, routed through the Bubble server
Log the user out
Server-side
Involves session management on the server
Update the user's credentials
Server-side
Requires server-side data updates
Make changes to current user
Server-side
Updates user data stored on the server
Send confirmation email
Server-side
Email sending involves server operations
Send password reset email
Server-side
Email sending involves server operations
Send magic login link
Server-side
Email sending involves server operations
Create an account for someone else
Server-side
Involves creating user data on the server
Check password for the current user
Server-side
Password verification requires server check
Assign a temp password to a user
Server-side
Requires updating user credentials on the server
Change the email for another user
Server-side
Involves updating user data on the server
Log out other user's sessions
Server-side
Session management requires server operations
Go to page ...
Client-side
Navigation is handled by the client. Loading the new page will incur workload, but is not a part of the action.
Refresh the page
Client-side
Page reload is managed by the browser. Reloading the new page will incur workload, but is not a part of the action.
Go to previous page
Client-side
Browser history navigation is client-side
Open an external website
Client-side
Opening links is managed by the browser
Add a pause before next action
Client-side
Delays are managed by the client
Terminate this workflow
Client-side
Workflow control is handled client-side
Create a new thing...
Server-side
Involves database operations
Make changes to thing...
Server-side
Updates data stored on the server
Make changes to a list of things...
Server-side
Batch updates involve server-side processing
Delete thing...
Server-side
Requires server-side data removal
Delete a list of things...
Server-side
Batch deletions involve server-side processing
Copy a list of things...
Server-side
Data duplication is managed on the server
Set a thing's slug...
Server-side
Slug setting involves server-side updates, as well as confirming the slug is unique
Download data as CSV
Server-side
Data export involves server-side processing
Upload data as CSV
Server-side
Data import requires server-side processing
Delete an uploaded file
Server-side
File management involves server-side operations
Send email
Server-side
Email sending involves server operations
Send meeting request by email
Server-side
Email sending involves server operations
Send Facebook Message
Server-side
Involves external API communication routed through the Bubble server
Show
Client-side
Element visibility is handled by the client
Toggle
Client-side
Element visibility is handled by the client
Scroll to
Client-side
Scrolling is managed by the client
Set focus
Client-side
Focus control is managed by the client
Display data
Client-side
Data display is managed by the client, but may involve loading data from the server
Display list
Client-side
Data display is managed by the client, but may involve loading data from the server
Show next
Client-side
Handled by the client, but may involve loading more data from the server
Go to page
Client-side
Navigation is handled by the client
Show message (alert element)
Client-side
Messages are displayed by the client
Animate
Client-side
Animations are rendered by the client
Set state
Client-side
Custom state management is handled by the client
Reset inputs
Client-side
Input reset is managed by the client
Reset data
Client-side
Data reset is managed by the client
Show previous
Client-side
Handled by the client, and the data will already be loaded on the server
Clear list
Client-side
Clearing a repeating group is managed by the client
Scroll to entry
Client-side
Scrolling is managed by the client
Trigger a custom event
Client-side
Custom events are handled by the client
Schedule a custom event
Client-side
Custom event scheduling is handled by the client
Trigger a reusable element event
Client-side
Custom events are handled by the client
Schedule API Workflow
Server-side
Involves API and server-side processing
Schedule API Workflow on a list
Server-side
Batch API operations are managed by the server
Set/cancel a recurring event
Server-side
Recurring events involve server-side management to set and cancel, as well as each time they run
Cancel a scheduled API Workflow
Server-side
Canceling scheduled workflows involves server-side operations
Dynamic expressions
Workflows can contain various dynamic expressions that sometimes involve the server, and the extent to which they do depends on the content of the expression. We delve deeper into dynamic expressions in the section below.
Elements
Elements are essentially client-side in nature, but still consume some workload to load. Additionally, elements can be set up in ways that require workload, such as setting a data source that queries the database.
To load and render an element is part of the page load workload process, and the number of elements doesn't change this processes value. After that, each element can contain dynamic expressions that require some server work:
Dynamic expressions
The element’s data source may be fetching data from the database
The element’s conditions may depend on server-side data sources
Any other fields that allow for dynamic expressions may also contain server-side data sources
Dynamic expressions
Elements can contain various dynamic expressions that sometimes involve the server, and the extent to which they do depends on the content of the expression. We delve deeper into dynamic expressions in the section below.
The placement of an expression does not affect its potential WU consumption. For example, two identical expressions placed in an element’s data source or in a condition will consume the same amount.
Element table
Let's review each element to determine if it requires server involvement.
The table considers a blank element placed on the page. Any workflows, dynamic expressions and conditions added to each element may require server communication.
Text
Client-side
Displayed and managed by the browser
Button
Client-side
User interaction handled by the browser
Icon
Client-side
Displayed and managed by the browser
Link
Client-side
Managed by the browser
Image
Client-side
Displayed and managed by the browser
Shape
Client-side
Rendered and managed by the browser
Alert
Client-side
Displayed and managed by the browser
Video
Client-side
Played and managed by the browser
HTML
Client-side
Rendered and managed by the browser
Map
Server-side
Rendered and managed by the browser, but requires an API call that is routed through the Bubble server
Built on Bubble
Client-side
Displayed and managed by the browser
Expression
Client-side
Evaluated and managed by the browser
Facebook Like
Server-side
Rendered and managed by the browser, but requires an API call that is routed through the Bubble server
Facebook Page
Server-side
Rendered and managed by the browser, but requires an API call that is routed through the Bubble server
Line/Bar Chart
Client-side
Rendered and managed by the browser
Dynamic expressions
The components of a dynamic expression
Dynamic expressions consist of three types of components: data sources, operators, and comparisons. While all three can be performed server-side, the processing location of the operators and comparisons depends on the data source component.
The data source
The data source is any source from which Bubble can pull data. As the list below suggests, some of these come from the database, others come from the client.
Note the following when reading the table:
Many of the data sources in the table can be extended with sub-data sources that can change the location from which it’s processed:
Example 1: The Current user data source is downloaded on page load, and handled client-side after that. However, adding more steps, such as Current User’s Company’s Name may lead to additional queries to the server.
Example 2: Arbitrary text as a data source depends on the Text property inside of it. This allows for dynamic expressions, which may add queries even if the arbitrary text by itself is handled client-side
In the majority of cases, API requests are routed through Bubble’s server for security reasons, and as such are handled server-side even if the actual request is made to a third-party server.
Current user
Client-side
User data is downloaded on page load, and available client-side after that.
Do a search for
Server-side
Involves querying the database
Perform a search using Algolia
Server-side
Uses external API for search, routed through the Bubble server
Get an option
Client-side
Option sets are downloaded on page load, and available client-side after that.
Arbitrary text
Client-side
Text is processed client-side, but the content in the argument may contain server-side.
Arbitrary date/time
Client-side
Date/time is processed client-side
Get data from an external API
Server-side
Involves external API communication, routed through the Bubble server in the majority of cases
Parent group's thing / Current cell's thing
Client-side
Data is already loaded, and the query is not repeated
Current cell's index
Client-side
Index is managed client-side
Current page thing
Client-side
Data is downloaded on page load
Element
Client-side
Managed client-side
This page
Client-side
Managed client-side
This element
Client-side
Managed client-side
Result of previous step
Depends
Depends on the previous step
Current Workflow thing
Depends
Depends on workflow context
Thing now
Server-side
Backend database triggers are always processed server-side
Thing before change
Server-side
Backend database triggers are always processed server-side
Get data from page URL
Depends
URL is processed client-side, but may point to a data source that is fetched from the server
Calculate formula
Client-side
Calculation is done client-side
Calculate loan payment
Client-side
Calculation is done client-side
Coordinates to address
Server-side
Uses external API for geocoding, routed through the Bubble server
Generate random string
Depends
Mostly calculated server-side, but sometimes client-side
Calculate sumproduct
Client-side
Calculation is done client-side
Website home URL
Client-side
URL is processed client-side
This URL
Client-side
URL is processed client-side
Current language
Client-side
Language setting is managed client-side
Operators and comparisons
Operators and comparisons follow the general rule of being performed server-side if one or more of the data sources are performed server-side. Because Bubble will attempt to finish the query in one process, without having to divide it between the server and client, the operators and comparisons will be context-dependent.
For example, if you are working with a search, such as the expression Do a search for Users:count the count operator will be performed on the server, and only the number of users (as opposed to the list of users) will be sent back to the client.
On the other hand, if you have already loaded a list of users into a repeating group, and reference this group using an expression like Repeating Group User’s List of users:count, the counting will be performed on the client, to save Bubble from having to transmit any data to the server.
The same is true for comparisons. Comparisons are used to compare two two compatible values, such as checking if a number is smaller, the same as or bigger than another number. The two numbers in this case would be the data sources, and whether this happens on the server depends on whether at least one of the data sources needs to communicate with the server
Searches and filtering
Many dynamic expressions involve database searches, often initiated with the “Do a search for” data source. Typically, these requests are processed entirely on the server.
To determine which parts of the process occur on the server and which might take place on the client, ask whether the data has already been downloaded. In essence, if the data is not yet downloaded, the operation will occur on the server. If it has been downloaded, further filtering or processing can occur on the client.
This applies not only to when you reference the result of an already-completed search (e.g. Repeating Group User’s List of Users), but also when you repeat two identical Do a search for data sources in different expressions on the same page.
Filters
In Bubble, lists can be further refined using the :filtered operator. This operator works similarly to constraints: Bubble processes the list by eliminating entries that don’t match the provided criteria. The final results are the records that remain after this filtering process.
Dynamic expressions in Bubble process from left to right, so the :filtered operator applies its elimination after the initial search is completed. This means it filters the results after the search has applied any regular constraints.
However, this doesn’t automatically move the process to the client. Bubble will try to complete the entire request on the server whenever possible, within a single request, which doesn’t add additional WU cost to the base search.
However, filters added to an already-completed request will, in most cases, be performed on the client. For example, if you have a repeating group of users and want to further filter the list by a field like age (using an expression like Repeating Group User’s List of Users:filtered), this filtering will be done instantly on the client side, with no WU cost.
Per-row filtering (advanced filters)
As we explored earlier, searches generally use one or more constraints to eliminate records that don’t match, returning the remaining list.
However, there are scenarios where this simple process of elimination isn’t enough, and some dynamic data needs to be calculated for each record for the search to complete. This essentially adds an examination process for every row in the database, potentially multiplying the search effort many times over.
Last updated