Hello everyone,
A few days ago, I discovered how to trigger backend workflows in a sequential manner (even though Bubble doesn’t support this natively). I’m sharing my solution with you because I would have loved to have a guide like this when I encountered this problem several months ago.
The Limitations of Workflows in Bubble
Here are some key limitations you should be aware of when working with workflows in Bubble:
- API Workflows triggered on a list run in parallel, not sequentially.
- Bubble prioritizes speed and efficiency, not strict linearity between backend workflow steps.
- Step dependencies (using “Result of step…”) become ineffective for complex systems.
- A Trigger Database Event cannot directly trigger another Trigger Database Event.
For more details, you can refer to discussions on the Bubble forum that explain these limitations better than I ever could.
My Solution: The “Filler Bucket” Method
The “Filler Bucket” method allows you to:
- Execute backend workflows sequentially.
- Ensure that a step only starts once the previous one is fully completed.
- Reliably track each step while maintaining optimal performance and reasonable WU usage.
How to Implement the “Filler Bucket” Method
To apply this method, you should be familiar with the following concepts:
- Trigger Database Events.
- API Workflows (Backend Workflows).
- Schedule API Workflow and Schedule API Workflow on a List.
- Option Sets and Data Types.
Step 1: Break Down Your Logic
Divide your objective into simple and clear steps. Break down the overall logic into specific actions.
Example:
- Step 1: Process a list of users to analyze them.
- Step 2: Generate a report for each user based on the analysis.
- Step 3: Send an email to the user with the results.
Each step must focus on a well-defined action and must not start until the previous one is fully completed.
Step 2: Build Your API Workflows
Create a separate API Workflow for each step. These workflows will perform actions on the ListOfItemStep’X’, which contains the elements being processed at each step.
Step 3: Create Statuses Using Option Sets
Set up an Option Set to track the progress of each step:
Start
.Step1
.Step2
.Step3
.Final
.
These statuses will monitor the process in your database, particularly in the BucketManager (explained below). You’ll need one status for each step in your logic.
Step 4: Configure the Data Types
Add two key data types:
1. BucketManager
The BucketManager tracks the overall process and manages associated data. It includes:
ListOfItemStep1
: The list of items to process in Step 1.BucketStep1
: The list of BucketFillers associated with Step 1.ListOfItemStep2
: The list of items to process in Step 2 (defined after Step 1 is complete).BucketStep2
: The list of BucketFillers associated with Step 2.Statut
: The global status (Option Set, e.g.,Step1
,Step2
) to track the current step.
You will need as many BucketStep'X'
and ListOfItemStep'X'
fields as you have steps.
2. BucketFiller
BucketFillers are created for each item in the ListOfItemStepX and track progress at the item level.
Statut
: The specific status of this item (Option Set, corresponding to Step’X’).BucketManager
: A reference to the BucketManager parent.
Step 5: Create the FillingLoop (Recursive API Workflow)
The FillingLoop is a backend workflow that associates BucketFillers with their BucketManager.
Input Parameters:
BucketFiller
(type BucketFiller).
Actions in the FillingLoop:
- Associate the BucketFiller with the BucketManager:
- Action: “Make changes to a thing”.
- Thing to change:
BucketFiller's BucketManager
. - Modification: Add
This BucketFiller
toBucketStepX
. - Condition:
This BucketFiller’s Statut = StepX
.This BucketFiller is not already in BucketManager's BucketStepX
.
- At the end, relaunch the FillingLoop:
- Action: “Schedule API Workflow”.
- API Workflow:
FillingLoop
. - Parameter:
BucketFiller = This BucketFiller
. - Scheduled date:
Current date/time + 5 seconds
.
Add a safeguard before the loop with a “Terminate this workflow when” condition to avoid infinite loops if no elements remain.
Step 6: Add Actions to Your API Workflows
Each API Workflow created in this tutorial Step 2 must:
- Create a BucketFiller for each item being processed.
- Associate the BucketFiller with the BucketManager and set the status corresponding to the current step (e.g.,
Step1
).
If triggered on a list of 15 items, this will create 15 BucketFillers with the Step'X'
status and the corresponding BucketManager.
Step 7: Set Up a Trigger Database Event to Launch the FillingLoop
A Trigger Database Event detects the creation of each BucketFiller to trigger the FillingLoop.
Condition:
- When:
BucketFiller now isn’t empty
.BucketFiller before change is empty
.
Action:
- Schedule API Workflow: Launch the FillingLoop with the
BucketFiller
as the parameter.
Step 8: Link Steps Using Trigger Database Events
A Trigger Database detects when all items in a step are completed before starting the next step.
Example: Transition Step 1 → Step 2
- Condition:
When BucketManager's ListOfItemStep1:count is BucketManager's BucketStep1:count
.And BucketManager’s Statut = Step1
.
- Actions:
- Update the Status: Move to
Step2
. - Update ListOfItemStep2: Define the elements for Step 2.
- Schedule the Next API Workflow: Trigger the workflow for the next list using “Result of step one ListOfItemStep2”.
Step 9: Clean Up BucketManager and BucketFiller
The final Trigger Database Event, under the condition:
When BucketManager's ListOfItemFinal:count is BucketManager's BucketFinal:count
.And BucketManager’s Statut = Final
.
Launches a cleanup workflow to delete all BucketManager and BucketFiller records and prepare for the next operation.
Conclusion
The “Filler Bucket” method allows you to trigger API Workflows sequentially in Bubble, bypassing its native limitations. This approach ensures each step is completed before moving to the next while maintaining performance and flexibility.
If you have any questions, feel free to ask or share your experience with implementing this method!
PS: I also have a way to apply this in the frontend, but I needed this backend version to ensure the process runs independently of the user being on the platform.