Adobe Launch

Launch : Async sequential

Hello world,

recently, I have realized an implementation on Launch that took advantage of the rule sequencing capability of Launch. I am using this blog post to share my experience and how you could use that to realize asynchronous operations synchronously.

Asynchronous Tag Management System

For Google Tag Manager (GTM) or Adobe Launch, it is very common to use an async tag on the implementation of the script in your page.
So the GTM or Launch tag looks like this:

<script src=”//” async>

Why to load in asynchronous mode ?

Loading a Tag Manager asynchronously has several implications and you need to be aware of them, so you can choose that configuration in all awareness.

  • It will take (slightly) longer to load
  • It will reduce the blocking time for your website
  • It will impact all tags present in your tag manager

From these points, there are 2 strategies that I see regularly at client site:

  • Optimize the load time of the page
    For obvious reasons (SEO, UX, …) some clients are focusing on reducing the load time of their pages. In that perspective, using an asynchronous implementation makes sense.
  • Optimize Tag Management System (TMS) load time
    Some clients are really dependent on the marketing or analytics tags present in the tag manager, so the goal of the optimization is to make the TMS available as soon as possible.

Sometimes, you have paradoxal goals, you want to do A/B test, and you want to optimize page load. Normally you have your A/B test tool in your TMS and your TMS is async. Unfortunately, the impact of the async method will most likely generate a flicker effect on your first page. Then some cache optimization can be done to prevent that to happen.

NOTE 1 : Async is (very) different from the defer tag, that push your script at the bottom of the priority load for your page.

NOTE 2 : Async does not change the size of your resource, it doesn’t speed up your dns lookup for that resources, there are other optimization possible if you are searching to save the last milliseconds.

Why is Launch special ? (or better?)

As you have seen, this capacity is pretty common for a TMS.
However, when you start to use asynchronous capability, you are entering a dangerous word. The world of the race conditions.

What is a race condition ?

To get a complete answer to that question, you can have a look at Wikipedia: You can see that this particular behavior happen on different fields; electronics, software, etc… Everytime that unknown timing and shared resources are present.

There are other nice thread on reddit about this, but to make it simple:

A race condition occurs when multiple processes (minimum 2) are trying to access the same resource at an undefined time, and the state of that resource is not stable over a large period of time.
Depending on the process timing, the resource will present different states, inconsistent data are then used in the processes/applications.

What is especially annoying is that these type of errors are hard to identify and reproduce.

How is Launch helping ?

Adobe Launch propose a configuration on its container to enable rule sequencing.
This has been proposed and presented on an experience league article (not the best medium to be honest), but you can find that post here.

You have to modify the Property setting of your container to enable that (it should be the default behavior for newly created properties)

The idea is pretty clever and quite powerful. Launch manages a queue of events and for each of the rule, there will also be a queue.

Before that feature, the asynchronous nature of tag execution, as it exists in GTM, was to ensure the correct order of the element fired based on events but it did not ensure a specific order within that event (if 2 rules were to fire on the same event) or the ensuring the completion of a script before firing the next one, but we will come back to that last point later.

In order to help on the visualization, I created 2 schemas to present the normal async load and execution of the script and the new one.

Default behavior for TMS async load

In contrary the Launch container with rule sequencing CAN ensure the following execution:

Because executing the different rules are dependent on the action of the preceding rule, but the total time of execution of these actions are not tracked, we can have some action of following rule starting before the last rule is finished running (shown in the first schema).

Let’s be honest, that is usually not a problem for 90% of the rule execution but for your analytics tracking, that can be problematic, as they can interfere with the tracking data and place the different tracking request out of order.

However, you can see that thanks to the new logic in place in Launch, you can ensure that the action is finished before you execute the next one.

What happens in the background ?

In the background, Launch is encapsulating (or wrapping) all the Javascript code you put in your custom code in a promise. The promise is then used to ensure that the code execution is done correctly.

On top of that, the different rules are arranged in a queue, that execute one rule after another. Ensuring sequencing again between the rules. This time, depending on the order specified in the Event.

Here is the screenshot of on Event configuration:

That is pretty neat but it has some limitation/implication:

  • If one of the action fails, the rest of the action following this one are not executed.
  • There is a timeout to set in the action (the promise only wait for the amount of time specified there)
  • It only really works (natively) if you are only doing synchronous tasks
    • That is already a problem for element that needs to be downloaded from the network.
      Any custom code action in a rules that is not firing on “Library Loaded” is externalized in a separate resource.
      The timeout starts when you start requesting that resource, if you have a slow network, only the download time can make you reach the timeout.

The limitation can be problematic for some use-case.
Fortunately, there are ways to realize asynchronous tasks with Launch and still wait for the action to trigger the next one.

Using Promises in Launch

During this year, one important upgrade of Launch that should have been given quite a louder release is the ability to use ES6 and especially promises in the Action or Condition of your rule.

Important Note: You cannot use promises in Data Element, or realize asynchronous action in Data Element. Only for Conditions and Action.

When you want to wait for a specific asynchronous task with your Tag Manager, you can now directly use a promise and return the promise in that action or condition.

The fact that you need to return that promise in the Action (or condition) is quite unorthodox. You do not return anything from an action usually, and therefore, it feels counter-intuitive to do so.

However, that is the way to do in order to override the Action / Condition promise wrapping that is normally happening for custom code script.

It should look something like this:

Launch Action – returning promise


I can give you an example on how I use that for my one of my client implementation.

My client has an important dependency regarding GDPR consent approval and requires us to run a script (not hosted in Launch) before we could run any action with Launch.

This script being loaded asynchronously and Launch as well, we could easily encounter race conditions issue when both script loads at the same time, sometimes one before the other, etc…

Having the rule sequencing enabled, and a promise to wait for an event from that script, was allowing to ensure the sequencing of the events in an asynchronous world.
Because rules are queued one after the other and each rule is waiting for each action inside them to finish before, you can make your whole implementation* wait for a specific dependency.
That is pretty neat.
* rules, Extensions are executed with Library Loaded event

I hope this article was helpful to get a view on a more advance Launch capability.

Leave a Reply

Your email address will not be published. Required fields are marked *