Queueable Apex

Take control of your asynchronous Apex processes by using the Queueable interface. This interface enables you to add jobs to the queue and monitor them, which is an enhanced way of running your asynchronous Apex code compared to using future methods.

For Apex processes that run for a long time, such as extensive database operations or external Web service callouts, you can run them asynchronously by implementing the Queueable interface and adding a job to the Apex job queue. In this way, your asynchronous Apex job runs in the background in its own thread and doesn’t delay the execution of your main Apex logic. Each queued job runs when system resources become available. A benefit of using the Queueable interface methods is that some governor limits are higher than for synchronous Apex, such as heap size limits.
Queueable jobs are similar to future methods in that they’re both queued for execution, but they provide you with these additional benefits.
  • Getting an ID for your job: When you submit your job by invoking the System.enqueueJob method, the method returns the ID of the new job. This ID corresponds to the ID of the AsyncApexJob record. You can use this ID to identify your job and monitor its progress, either through the Salesforce user interface in the Apex Jobs page, or programmatically by querying your record from AsyncApexJob.
  • Using non-primitive types: Your queueable class can contain member variables of non-primitive data types, such as sObjects or custom Apex types. Those objects can be accessed when the job executes.
  • Chaining jobs: You can chain one job to another job by starting a second job from a running job. Chaining jobs is useful if you need to do some processing that depends on another process to have run first.

Example

This example is an implementation of the Queueable interface. The execute method in this example inserts a new account.
1public class AsyncExecutionExample implements Queueable {
2    public void execute(QueueableContext context) {
3        Account a = new Account(Name='Acme',Phone='(415) 555-1212');
4        insert a;       
5    }
6}
To add this class as a job on the queue, call this method:
1ID jobID = System.enqueueJob(new AsyncExecutionExample());
After you submit your queueable class for execution, the job is added to the queue and will be processed when system resources become available. You can monitor the status of your job programmatically by querying AsyncApexJob or through the user interface in Setup by entering Apex Jobs in the Quick Find box, then selecting Apex Jobs.
To query information about your submitted job, perform a SOQL query on AsyncApexJob by filtering on the job ID that the System.enqueueJob method returns. This example uses the jobID variable that was obtained in the previous example.
1AsyncApexJob jobInfo = [SELECT Status,NumberOfErrors FROM AsyncApexJob WHERE Id=:jobID];
Similar to future jobs, queueable jobs don’t process batches, and so the number of processed batches and the number of total batches are always zero.

Testing Queueable Jobs

This example shows how to test the execution of a queueable job in a test method. A queueable job is an asynchronous process. To ensure that this process runs within the test method, the job is submitted to the queue between theTest.startTest and Test.stopTest block. The system executes all asynchronous processes started in a test method synchronously after the Test.stopTest statement. Next, the test method verifies the results of the queueable job by querying the account that the job created.
01@isTest
02public class AsyncExecutionExampleTest {
03    static testmethod void test1() {
04        // startTest/stopTest block to force async processes
05        //   to run in the test.
06        Test.startTest();       
07        System.enqueueJob(new AsyncExecutionExample());
08        Test.stopTest();
09         
10        // Validate that the job has run
11        // by verifying that the record was created.
12        // This query returns only the account created in test context by the
13        // Queueable class method.
14        Account acct = [SELECT Name,Phone FROM Account WHERE Name='Acme' LIMIT 1];
15        System.assertNotEquals(null, acct);
16        System.assertEquals('(415) 555-1212', acct.Phone);
17    }
18}
Note
The ID of a queueable Apex job isn’t returned in test context—System.enqueueJob returns null in a running test.

Chaining Jobs

If you need to run a job after some other processing is done first by another job, you can chain queueable jobs. To chain a job to another job, submit the second job from the execute() method of your queueable class. You can add only one job from an executing job, which means that only one child job can exist for each parent job. For example, if you have a second class called SecondJob that implements the Queueable interface, you can add this class to the queue in theexecute() method as follows:
1public class AsyncExecutionExample implements Queueable {
2    public void execute(QueueableContext context) {
3        // Your processing logic here      
4 
5        // Chain this job to next job by submitting the next job
6        System.enqueueJob(new SecondJob());
7    }
8}
You can’t chain queueable jobs in an Apex test. Doing so results in an error. To avoid getting an error, you can check if Apex is running in test context by calling Test.isRunningTest() before chaining jobs.

Queueable Apex Limits

  • The execution of a queued job counts once against the shared limit for asynchronous Apex method executions.
  • You can add up to 50 jobs to the queue with System.enqueueJob in a single transaction.
  • No limit is enforced on the depth of chained jobs, which means that you can chain one job to another job and repeat this process with each new child job to link it to a new child job. 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.
  • When chaining jobs, you can add only one job from an executing job with System.enqueueJob, which means that only one child job can exist for each parent queueable job. Starting multiple child jobs from the same queueable job isn’t supported.

Counters