4

As mentioned here

Because no limit is enforced on the depth of chained jobs, you can chain one job to another. You can repeat this process with each new child job to link it to a new child job.

What are the possible drawbacks? I don't see any resources limitations like heap or CPU time as each queueable takes place in new transaction. The only limitation I see is the:

The maximum number of asynchronous Apex method executions (batch Apex, future methods, Queueable Apex, and scheduled Apex) per a 24-hour period: 250,000 or the number of user licenses in your org multiplied by 200, whichever is greater

1
  • FYI you can also chain batch jobs using System.scheduleBatch method which has a benefit of adding delay if needed.
    – dzh
    Jul 30 at 3:19
10

The primary limitation you will face is throttling. Once you surpass a chain depth of 4, Salesforce will slow you down to 15 seconds between executions. If you need to process a high volume of jobs, this limitation can be problematic, as it hard caps you at <6k jobs/day on a single chain.

Please note the specific numbers for chain depth and interval are based on orgs to which I have access, and may change in the future.

6
  • I haven't measured this myself, but I have also experienced a slowdown with similar chain depths. At the very least, this is an effect that needs to be considered.
    – Derek F
    Jul 28 at 21:48
  • We've invested very heavily in infinite chaining, it's definitely the only measurable drawback we have found.
    – Adrian Larson
    Jul 28 at 21:49
  • 1
    my experience is the throttle is 60 secs but as you say, YMMV. One thing you can do when hitting depth 4 is start a future and then restart the queueable chain - that is Q-Q-Q-Q-F-Q-Q-Q-Q-F-... this avoids the throttle (at least in our org)
    – cropredy
    Jul 29 at 3:46
  • 1
    Surprising, the interval has been shockingly consistent. We found that workaround as well but I was leery of describing it publicly.
    – Adrian Larson
    Jul 29 at 3:47
  • I ran some numbers recently in an APAC sandbox, using a queueable that did no work other than recording timestamps, chaining up to n, and yeah, in aggregate that 15 seconds was pretty consistent, though individually something could take half a minute. Hasn't yet been battle-tested in PRD though. See e.g. here i.imgur.com/bIEXUK4.png - a chain of 60 jobs, with a few spiking up to nearly 30 seconds. When I tested with jobs that did some fairly complex work, the numbers did go up slightly to about 17 seconds, but still in the same ballpark.
    – James Hill
    Jul 29 at 6:19
3

A very specific limitation is that you will face an exception being thrown when you run this on a dev org or scratch org. As per the documentation:

For Developer Edition and Trial organizations, the maximum stack depth for chained jobs is 5, which means that you can chain jobs four times and the maximum number of jobs in the chain is 5, including the initial parent queueable job

Both this limitation and the throttling issue mentioned by @AdrianLarson can be avoided by ensuring that you engineer the queueable to track stack depth and to switch execution to a future method once the maximum depth is reached (switching back to queueable again after that).

This has an impact on the state that the queueable can maintain since future methods can only receive (collections of) simple data values, and you need to use the method parameters to receive and propagate that state forwards down the queue.

NB: You also want to make sure that the future invocation also does useful work, as if it were an execution of the queueable, otherwise you're wasting one of your limited daily async calls every time you switch from queueable to future.

UPDATE: Using the following code on a scratch org demonstrates the error:

public with sharing class TestQ implements Queueable {
    private Integer depth = 1;

    public void execute(QueueableContext param1) {
        System.debug('TestQ depth is ' + depth);
        depth++;

        System.enqueueJob(this);
    }
}

Starting this via Anonymous Apex:

System.enqueueJob(new TestQ());

After 4 successful executions the following exception is thrown:

System.AsyncException: Maximum stack depth has been reached.

1
  • I've moved our discussion about whether or not this limitation still applies to chat.
    – Adrian Larson
    Jul 29 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.