Flow, New Release

Hidden Gem in Spring 23: Schedule-Triggered Flow Improvements

I can almost hear you! You read the Unofficial SF Sneak Preview by Adam White, and there are no Schedule-Triggered flow improvements in this next release.

So, where does this title come from? πŸ€”

The schedule-triggered flows are about to become immensely more helpful. Why is that?

Spring 23 is removing the 2,000 elements executed limit in flow interviews. If you followed me long enough, you will know I sparked a debate in 2021 about how schedule-triggered flows should be ideally structured. The challenge I faced was more related to record-locking issues than the 2000 limit.

What is the 2,000 elements executed limit? πŸ”’

When a flow executes, it goes down a particular path. It goes to a decision element, turns left, and executes 2 elements there. It then goes into a loop and processes 5 records. If there are 3 elements in the loop, that means another 15 elements are executed. All these add up to a total number for each flow interview. When a particular flow interview goes over 2,000 it throws an error. Please note the number of elements on the canvas is not what we count here; we count the elements on the execution path.

Paul McCollum, UXMC likes to live on the edge. He overcame this limit before by using platform events. You can see his session on Automation Hour here. This method won’t be necessary anymore.

The Achilles heel of Schedule Triggered Flows: 🦡

Schedule-Triggered flows are prone to record-locking issues because you cannot determine the sequence of records they will process. They randomly select what to process first.

What is a locking error? πŸ’»

When Salesforce processes a record, it momentarily locks the related records and makes them unavailable for processing. For example, let’s say you want to update an Opportunity. Related Account and Contact records will be locked during this transaction. When you have multiple updates happening simultaneously, your updates may try to update a locked record, which will not be possible. Why are schedule-triggered flows executing multiple updates at the same time? Because they are batched.

What is batching ❔

Salesforce batches certain operations it executes in default batches of 200 unless this is a parameter you can set; you can sometimes change the batch size. Where do you see this setting? When you import 1,000 records using the Data Loader, you can change the batch size in the settings. You can also set the batch size when you build a scheduled path in a record-triggered flow. You don’t have this setting in schedule-triggered flows. If 200 or more records fit your flow’s start element entry conditions, 200 flow interviews will be batched into one transaction.

This is where the trouble starts.

There here are two ways you can mitigate the locking error risk:

1️⃣ Decrease the batch size

2️⃣ Sort and process the records related to the same record together.

When executing a schedule-triggered flow, you don’t have these methods available.

What can you do? βœ…

You can set up your schedule-triggered flow to run on the parent record rather than the child. This will ensure that you process all the opportunities related to one account together.

Why was that not feasible before? ❌

When you looped through the related records and sometimes went one level further and looped through the related records of those records, you were almost guaranteed to hit the dreaded 2,000+ elements executed error. This used to be a typical use case where I recommended you go to an Apex code solution. Now you don’t have this problem.

Where is this useful? πŸ’‘

You can set up complex roll-up summaries that you don’t need to update immediately. Instead, run these at night when the kids are sleeping.

You can create and update custom object records to flatten your data for reporting ease. For example, if you could not get specific data to show next to each other on dashboards or create complex comparisons in reports, you can now facilitate this via a nightly scheduled-triggered flow job.

The schedule-triggered flow you see above looped through more than 1,000 opportunity records in one flow interview: That’s 2,000+ elements executed.

This is complex territory. I may have left out important points and even made errors in my evaluation. So please comment below and help me get a fruitful debate started.

This post was originally made to LinkedIn on December 13th, 2022.

Read the previous post: What Is The Vision For Flow Testing?

Flow, New Release

What Is The Vision For Flow Testing?

You showed great interest in flow testing when I wrote about it a few issues back. One of my concerns about this newly introduced GA functionality is that there is little documentation about it. 😟

When I shared this concern in Trailblazer communities, the Product Director for Flow Testing in Salesforce, Henry Liu, reached out. Henry and I had an open discussion on Zoom, and I asked him all the questions I had about testing. Please remember that this information is subject to the standard forward-looking statements disclaimer of Salesforce. Here is the recap of the questions I asked and the answers I received: πŸ’‘

  • Is flow testing for admins? Absolutely.
  • Will tests calculate coverage at some point? That is the vision.
  • Will a lower limit on test coverage be required before you can deploy flows to production? Salesforce asked admins this question, and the response they got was that this needs to be decided at the Org level. The vision is that this will be optional for the admin to decide.
  • Does flow testing show us that the flow will run without errors in production? Not exactly. Flow testing does not execute the actions inside the flow, for example. You can test whether the flow followed a certain path, but you won’t know that the flow action won’t yield errors when executed.
  • What should admins study to understand the principles of testing before tackling flow tests: Code testing and Apex test classes.
  • Where do you see this functionality will take us? What is the grand vision? In a couple of years, we should have an automated testing functionality that can test everything custom in Salesforce Orgs, including code.

I think the last point presents a potential future career opportunity for admins. Please note that we should expect Trailhead content on flow testing in the future. Here is a blog post by Jennifer W. Lee on this functionality.

I would like to thank Henry for his time.

This post was originally made to LinkedIn December 5th, 2022.

Read the previous post: Are You Using the Cut Functionality?


Are You Using the Cut Functionality?

I use the flow canvas in autolayout mode. πŸ€–

Before the last release, I went back to freeform whenever I added a decision element in the middle of my flow. When you do that, you get a decision element with multiple empty outcomes, all leading to the next element in flow. πŸ€¦β™‚οΈ

That means you need to rearrange your elements: a few of the existing elements need to go under various outcome branches, and often a few new ones need to be added. I tried reconnecting the outcome branches to the existing elements to get what I wanted, but this did not work very well in most cases. 😀

I went to freeform to delete connectors and reconnect them the way I wanted. Sometimes I could go back to autolayout; some other times, this did not work. In those cases, I had to continue in free form.

Now we have a new powerful tool in the autolayout mode; cut element functionality. I am not positive you all use this. Therefore, I wanted to make sure I remind you that it is there for you to use. βœ‚οΈ

Instead of playing with the connectors and rearranging them you can now point to an existing element in your flow, cut it, and then paste it on one of the decision paths. πŸ“’

Some of you may say, we had copy and paste, what is the big deal? This is partially true. You can use copy and paste to create a copy of the current element, but copy and paste renames the element and its components because the original ones are still on the flow canvas. The names have to be unique. Even if you delete the original one, you end up with an unnecessary renaming job you have to complete. 😫

If you have yet to try cut and paste elements, give it a try now. And if you are still using freeform, give autolayout a try; you will like it. I hardly ever go to free form now. πŸ™

This post was originally made to LinkedIn on November 14th, 2022.

Read the previous post: Do We Know How Scary Flows Are?

Flow, New Release

Flow Testing Is Here: Exciting News!

Salesforce recommends developing custom code and custom low-code in Sandbox Orgs and performing thorough testing before deploying them to production.

For code, Salesforce enforces test coverage: You need to run tests and ensure 80% or more test coverage for all your custom code before you can push your code to production. This means your test classes have to cover 75+% of the custom code lines in your Org.

For flows, there is no such requirement. You could develop in production or deploy flows without testing first in the Sandbox. However, this approach is not recommended.

Until now, there was no easy way to run and rerun prebuilt tests for your flows similar to the test class functionality for code.

With Winter 23 Release, you received the flow testing functionality (GA) that gives you this feature for record-triggered flows.

Why would you use flow tests?

  • Flow tests make rerunning the tests by you or your colleagues much easier and faster. ⏩
  • When you build new automation, you can now run/rerun all existing tests in your Org. ♻️
  • Before Salesforce releases, you can retest your existing flow automation running on the new API version for release readiness purposes. πŸ’»

How does it work? How do you create flow tests in Salesforce? There are two ways:πŸ§ͺ “Convert to test” button: Run a debug and convert the successful debug run to a flow test.πŸ§ͺ “View tests” button: Open the tests screen and create a test using the wizard.

There are three main components to a flow test in Salesforce:1️⃣ Set test details: Set parameters such as Create/Update, and Immediate/Scheduled Path.2️⃣ Set triggering record: Set the field values for the test record, including values for after update if the test is for update.3️⃣ Assertions: Set the expected outcome and custom error messages if the expected outcome is not observed.

What are assertions? Assertions are logical statements that can evaluate as true or false. They are intended to test the expected outcome of the flow automation to decide whether the flow passed the test or not. A good example is “Does Opportunity Stage equal Qualification?”: True/False.


  • Test records: When you create your test, you can point your test to a record. As a result, the test inherits the field values from this record. However, you can modify these field values before finalizing your test. Your test is not linked to this record but contains and uses its field values.
  • Decision outcomes automatically create boolean variables. The variable is set to true when the flow goes down the associated path.
  • Actions in flow may create output variables. You can check the value of this variable. Some actions may not have any output variables. Then it becomes a difficult task to check whether the action was completed successfully. Email Alerts seem to auto-create a boolean variable with the same name. I assume this means the action was completed successfully, but I am not sure. I am still researching this topic.
  • You can use the “Was Visited” operator to evaluate whether a particular element was visited on the executed flow path.


  • There is limited information out there about flow testing. The release notes site for Winter 23 has a dedicated page that contains only a brief paragraph. This is not sufficient.
  • Update: Followers reported tests are visible in change sets (Check the comment by Yumi below). /*I don’t believe you can deploy these tests via a change set. If you are working with change sets, this is a significant limitation. You will refresh your Sandbox eventually, and you may lose the tests in it.*/

This post was originally made to LinkedIn on October 24th, 2022.

Read the previous post: Migrate to Flow Best Practices

Flow, New Release

Winter 23 Flow Usability Improvements Will Make Your Life Easier

Winter 23 comes with several flow usability improvements:

  • The toolbox left panel is turned off by default in auto-layout to make more screen space.
  • Element search on the Add Element screen supports text search for element names and subflows & actions.
  • Salesforce is reporting now that the canvas is bigger with more area to play with.
  • Screen configuration screen in screen flows takes up more screen space to allow more visibility for columns and component previews.
  • Update related records in Record-Triggered Flows got easier: A dedicated radio choice has been added.

Let me show a few of these with supporting images: add element dialogue now supports text entry. Elements, subflows, and actions are returned and displayed on the screen in response to the text search.

When you added a screen element in your flow builder, the configuration screen took a smaller portion of the screen, which made working with the screen design difficult. Now you get a bigger configurator window.

Updating records related to the records that triggered your flow got more guidance with this dedicated radio choice in the Update Records element.

What do you think?

This post was originally made to LinkedIn on September 14th, 2022.

Read the previous post: Winter 23 Flow Formula Syntax Check

Flow, New Release

Winter 23 Flow Formula Syntax Check

Winter 23 brings you a “check syntax” button on the formula resource configuration screen. Previously we had this functionality only for the collection filter and the start element screens. What did you need to do before this release when debugging your formula resources?

  • You created formula resource(s) and closed out the screen for the formula resource configurator.
  • You saved the flow.
  • You received one or more error messages. These may be related to one or more formula resources.
  • You went back into the formula resource(s).
  • You made corrections and closed out the formula resource configurator.
  • You saved the flow again.
  • You rinsed and repeated. 😫

Now you will do this:

  • Build your formula on the formula resource configurator screen.
  • Click on the “check syntax” button on the same screen.
  • Review the error message and correct the error. Click on the same button and repeat. βœ…

Needless to say, this will bring significant improvement in efficiency.

Now that I have received this functionality, I will ask for one more thing. I know I am getting spoiled:

A formula builder and syntax check in decision elements.

I did not know I needed this. But wouldn’t it be awesome?


This post was originally made to LinkedIn on October 9th, 2022.

Read the previous post: HTTP Callout in Salesforce Summer 23 – POST (Beta) – 3/3

Flow, New Release

HTTP Callout in Salesforce Summer 23 – POST – 3/3

Now, you will build the flow you will host on the community (digital experience) site.

Important note: We will set this flow up to run at the System context without sharing under the Advanced Flow settings.

This simple flow gets an opportunity using the record Id as input and displays critical field values on the screen. Note that a decision is built to handle no or invalid recordId input.

Here is what the Display Text component looks like in the Screen Element.

Once you complete your flow and activate it, create a public community (digital experience) site and add your flow to the main page. Several steps must be followed to set up guest user access properly. We will not go into these steps in this post. Comment below if you need a follow-up post with detailed steps, please.

Once you set up your community, you can pass the recordId as a URL parameter to your flow to see the Opportunity record field values on your screen. You see the long URL in the browser address bar below.

Now, set up a simple record-triggered flow to populate the URL (long URL) field on the Opportunity record. Here is how you do it.

Now set up another record-triggered flow to send an email with the short URL to the owner of the record.

Your email action looks like this in Summer 23 (Yay!).

Your email body text template will look like this.

Your email will look can be seen in the image below. You may think it is silly to shorten the URL by looking at this since we can hide it in an HTML email. That is correct, however, the actual value add is when you need to text (SMS) the link. Short URL looks much better.

After debugging and activating all your flows, you can create a new Opportunity like the one below. Hint: Cloning and modifying a few field values work well when testing.

Voila: Your long URL and short URL are populated, and the email was sent to the record owner’s email inbox.


Note: These posts were written as a result of a collaboration between Josh Dayment and Andy Engin Utkan. I want to thank Josh Dayment for his relentless efforts and countless trials to get this demo to work.

Related Links:

Create HTTP Callout – POST 1/3

Create HTTP Callout – POST 2/3

Create HTTP Callout – GET

Flow, New Release

HTTP Callout in Salesforce Summer 23 – POST – 2/3

In the flow builder, you must add an action element for the HTTP Callout.

Before you do that, let’s set up the Named Credential the Callout needs.

In setup, go to Named Credentials, select the second tab for the External Credentials, and click on New.

Set up your External Credential as follows.

Per Bit.ly API documentation, your header must pass the Access Token to the Bit.ly API. Generate your Access Token on Bit.ly, as seen below.

Your Access Token will be saved in Principals under Named Credentials. Set it up as follows.

Paste the Access Token form Bit.ly into the value field.

Now your Principle is ready to be used.

The Bit.ly API expects the Access Token to be passed in the header. This is the header section that you will need to set up.

Create your first custom header as follows.

One more custom header is needed. Set it up exactly like in the image below.

Now you are ready to complete your Named Credential setup.

Having set up all parameters the HTTP Callout needs, go to your flow to create the action. Insert an action element and click on “Create HTTP Callout”.

Give it a Name and choose the Named Credential you created. Click Next.

Set up the following parameters.

Get your example request and response JSON here: https://dev.bitly.com/docs/tutorials/shorten-customize-links/

Paste the JSON and click on Review. Hit Done.

Do the same thing for the response. This will create the Apex Defined Variables.

You should see two checkmarks after you click on Done above. Once you complete these steps, your HTTP Callout will be ready.

Now let’s set up the remaining flows and the community (digital experience) site.

Please continue to the third post by clicking here.

Related Links:

Create HTTP Callout – POST 1/3

Create HTTP Callout – POST 3/3

Create HTTP Callout – GET

Flow, New Release

HTTP Callout in Salesforce Summer 23 – POST – 1/3

HTTP Callout in Spring 23 got many people excited. The blog post and the video by Josh Dayment and I drew quite some attention. We heard one criticism for this functionality: the solution was incomplete without the POST method.

With Summer 23, the Salesforce Flow Product Team not only moves the GET method to GA, but also gives us the POST method in Beta.

The use case we picked for this demo is based on a real-life client requirement. The client wants to shorten the long URL links before they send them to customers via email or text. Text (SMS) requirement is very important because we cannot hide the long URL behind a short label there since SMS does not support rich text. I don’t have texting set up in my preview Org, therefore, I will demo this using email.

The solution consists of many parts. The list is as follows:

  • Bit.ly is the service that supports an API with a POST method to shorten URLs. We will need an account with Bit.ly. The good thing is they allow us to use the service for free until we reach a certain number. (1)
  • A record-triggered flow with an async path that uses the HTTP callout to Bit.ly to shorten the URL (2)
  • A public digital experience (community) site that houses a screen flow to display the critical field values for the Opportunity (3)
  • A screen flow that runs at system context without sharing to show the critical Opportunity field values on the community site. (4)
  • A simple record-triggered flow to create the long URL on the record (this can also be a formula field) (5)
  • A simple record-triggered flow that generates the email with the short link. (6)

And a few custom fields on the Opportunity object: URL (long) and Short URL text fields and a Short URL Requested checkbox field.

First, we go to Bit.ly to create a free account. They have API documentation available. However, I cannot say the documentation is very clear. Here is the relevant settings page we need to create the access token for the API.

*I wiped my values from the screenshot; you will need to copy yours by going to this screen.

We will come back to this later.

Let’s walk you through the flow that will execute the HTTP Callout.

Create these custom fields on the Opportunity object:

URL (Text)

Short URL (Text)

Short URL Requested (Checkbox)

Then create the HTTP callout async record-triggered flow.

This is how the flow looks after it is completed.

Set up the start element as follows.

Build an assignment element to assign field values. You will assign the input parameters Bit.ly API needs to the Apex defined variable that the “Create HTTP Callout” builder provides us. Initially, enter a fixed URL here, such as SalesforceBreak.com, until you can get the flow to work without issues.

Get your group Id from Bit.ly from your browser address bar when you display this screen here.

The only input parameter that the callout action needs is the Apex defined variable.

The short URL is again inside an Apex defined variable under 2XX>link. We will update this value to the short URL custom field of the Opportunity record.

But you can do all this after properly creating your HTTP callout action. And that requires a few steps.

Read the next post to learn how the HTTP Callout action is set up.

Please continue to the second post by clicking here.

Related links:

Create HTTP Callout – POST 2/3

Create HTTP Callout – POST 3/3

Create HTTP Callout – GET