This blog post was written in collaboration with Michael Halliwell, one of Gearset’s DevOps Leaders.
Salesforce offers a wide range of options for automating business processes. In this post we take a close look at schedule-triggered flows: what they are, when to use them, and how to build them.
What is a schedule-triggered flow?
Schedule-triggered flows launch at specific times and frequencies. They’re a huge benefit for teams looking to automate repeatable tasks they carry out on a set cadence.
Schedule-triggered flows vs. scheduled batch Apex
Schedule-triggered flows are pretty much equivalent to scheduled batch Apex, except they’re built with clicks not code. There may be use cases where Apex batch jobs are still needed because schedule-triggered flows have lower limits:
- A schedule-triggered flow can query up to 50,000 records. Each record retrieved represents an interview, and you can’t exceed 250,000 interviews a day with schedule-triggered flows (or 200 x your number of user licenses if that’s greater). By contrast, batch Apex can query up to 50 million records.
- The maximum batch size for schedule-triggered flows is 200; for batch Apex it’s 2,000.
Schedule-triggered flow vs. scheduled path
There are a couple of different scheduled flows available in Flow Builder, each suitable for different use cases. Schedule-triggered flows run at the time and cadence you set. Scheduled paths are triggered by records — but you choose when the automation runs, relative to the time the record changes. For example, a schedule-triggered flow might run at 2am every day. A scheduled path might run 24 hours after a case is created, or two weeks before a renewal date.
What to consider when setting up a schedule-triggered flow
Salesforce offers a handy list of schedule-triggered flow considerations. Most are fairly intuitive, but there are a few important gotchas to watch out for:
- If your flow stops working, check whether it’s been deleted on the Scheduled Jobs page in Setup. If it has been removed as a scheduled job, deactivate and reactivate the schedule-triggered flow to get it back in action.
- A schedule-triggered flow can’t make callouts unless it includes a Wait element first.
- A schedule-triggered flow will fail if it invokes Apex and you’ve enabled the update
Require user access to Apex Classes invoked by flow
. - A schedule-triggered flow will also fail if you have an Update Records element that tries to write values to read-only fields. You need to switch on the process automation setting
Filter inaccessible fields from flow requests
. - If your flow has a trigger, you’ll need the
View All Data
permission.
How to build a schedule-triggered flow in Salesforce
Let’s walk through an example use case that’s well suited to a schedule-triggered flow.
Imagine your accounting department manages the activation and deactivation of accounts in Salesforce. Currently, they’re running reports each week and manually updating the status of accounts to “active” or “inactive” based on the contract start/termination dates. Accounting has requested automation that looks at the contract start/termination dates every night and automatically activates or deactivates these accounts. It’s the perfect time to use a schedule-triggered flow!
Of course, this is just an example of how a schedule-triggered flow might work. In practice, your flow might need different things like the Create Records element, the Delete Records element, the Assignment element, an Apex Action, Custom Error, or Email Alert. There are plenty of options to cover a wide range of use cases — this walkthrough will give you a sense of a few things to watch out for.
1. Create a schedule-triggered flow
Let’s go ahead and build our flow! First, we create a new flow and choose the Schedule-Triggered Flow option.
Once the Flow Builder opens, click on the Start element. There are two options: Set a Schedule and Choose Object. Click Set a Schedule to choose the start date, start time, and frequency that the flow will run. Let’s schedule the flow to start on the 19th of October, and then run every night at 1:30am.
The Start element acts like a Get Records element. When this run is triggered, it’s actually going to run this flow for one record at a time. Each record gets stored in a single record variable called $Record
, so you won’t need to loop through your results.
Click Choose Object to specify which object will be queried when the schedule-triggered flow launches. Select Account
as your object.
There are a few options for filtering which accounts are queried:
- None — Run Flow For All Accounts
- All Conditions Are Met (AND)
- Any Condition Is Met (OR)
- Custom Condition Logic is Met
As these options are limited, it’s usually better to add in your logic later in the flow using a Decision element. So let’s pick None — Run Flow For All Accounts
in our Start element, so that all our account records will run through our flow.
Once you’ve chosen your object and filter conditions, click Done.
2. Create the logic for a schedule-triggered flow
With our Start element completed, let’s create the custom logic for our flow.
In this case, we want to automatically update records based on their contract start or termination date. To do this, the flow will first need some logic to find today’s date. Using the New Resource section on the left-hand toolbar, create a formula variable that returns today’s date. Use the data type date
, type in the formula TODAY()
, and give the API name returnTodaysDateFormula
.
Now we have a formula that returns today’s date, we can reference it in our Decision element to see if the account should be terminated or activated.
To do this, we’ll create a Decision element that follows directly after the Start element. Each Decision element automatically has a “default outcome”, which is used if the object in the flow doesn’t trigger any changes. You can create different outcomes for your Decision element. We’ll create two here: one for account termination; one for account creation. Let’s take a look at the logic for each.
For the termination logic, we want an account to be terminated if its contract end date is today. So instruct the Decision element to look at the resource record’s Contract End Date
and check whether this is today’s date. Refer back to the formula we created earlier, by choosing the operator to be Equals
and value to be returnTodaysDateFormula
.
For the activation logic, we need to create a new outcome for contracts that need to be activated. Use the same logic as for the termination outcome, but access the resource Contract Start Date
instead.
3. Create the assignments from our logic
Now that our Decision is created, let’s add two Assignments — one after each decision outcome. Each Assignment will assign a status of active
or inactive
to the current record in the flow. Once again, we’re referencing the $Record
variable.
The termination Assignment will update the variable $Record Status
to Terminated
.
The activation Assignment will update the variable $Record Status
to Active
.
The next step is to connect the elements, so the flow looks something like this:
4. Complete the flow
Finally, add an Update Records element. Both Assignments can terminate to the same Update Records element, as they both reference the same $Record
variable.
You can choose how the Update Records element finds which records to update. For this example, select Use the IDs and all field values from a record or record collection
. You’ll also need to select which record(s) to update.
Once you’ve created your Update Records element, you’ll need to attach both the activation and termination Assignments. The end result will look something like this:
You can now save the flow and you’re ready to deploy it!
How to deploy a schedule-triggered flow using change sets
It’s possible to deploy flows using change sets, but there are some key challenges:
- Flows have a lot of dependencies, and you’ll need to include all of them in the deployment. With change sets, it isn’t easy to identify those dependencies. As you’ll see, Gearset gives you visibility into the process.
- There are a number of issues with flows that cause deployments to fail, particularly around flow versions. Gearset offers automatic fixes for those problems.
- You can’t deploy any destructive changes (deletions) using change sets. So if you need to remove a flow, you’re left to do that manually from production — which is obviously risky. Even with tools that do support deploying destructive changes, flows can still be tricky. Gearset has some unique functionality so you can delete flows easily and safely.
How to deploy a schedule-triggered flow using Gearset
Deploying your schedule-triggered flow along your release pipeline is nice and easy with Gearset. If you want to keep following along with this walkthrough, and you’re not already a Gearset user, you could start a free trial — it doesn’t take long to get set up.
From Gearset’s Compare and deploy screen, choose your source and target orgs. Click the Metadata comparison filter and then Manage custom filters. Check here that the filter includes the Flow
and Custom object
metadata types.
At the comparison screen, select the flow. Gearset will recognize the dependencies and add them to the deployment package.
Click Next. From the Deployment summary page, it’s a good idea to validate the deployment by clicking the button in the bottom-right corner — this allows you to see if the deployment will work before committing.
Assuming everything looks fine after validating, you’re ready to hit Deploy now! If you need to roll back the deployment, you can do that from your deployment history in Gearset.
Go with the flow!
Building and deploying flows can be tricky, but with help from the community and platforms like Gearset, you can build and release a flow that works for you. To try deploying your schedule-triggered flow, or any other metadata for that matter, definitely give Gearset a go on a free 30-day trial. Or book a demo to get a guided tour of the whole platform.