Future Vs Queueable Apex (2024)

What is the difference between future method and Queueable Job in Apex? Join us to learn about Future Vs Queueable Apex. Instead of directly jumping on to learn about the future and queueable apex first we will learn about what is synchronous process and why we need use asynchronous apex.

Table of contents

Synchronous Process

In simple words we can say executing a class based on single thread that is nothing but execute one method at a time either using top down or bottom to top approach.

Example: Imagine you have a requirement like when you insert a contact or delete a contact update the account with number of contacts and then you need to perform web service callout for that account. Using the synchronous apex is no-no situation because we always need to deal with the governor limits and apex CPU time. So how can we solve this situation.

Can we solve this problem using the asynchronous process?

Asynchronous process

The answer is yes, asynchronous process will execute in its own thread it is independent. So how many asynchronous flavors we have in salesforce?

I would say as of today we have total of 4 flavors. Out of 4 do we have any asynchronous process that is annotation based. So, we need not to write a separate class and handle the asynchronous process.

Future Vs Queueable Apex (1)

Do not worry we have that in Salesforce. It is nothing but @future annotation how cool it is right. Now we are ready to deep dive into learn about the future asynchronous process

So, what exactly is @future annotation?

@future annotation will start when the resources are available, and they will run on their own thread. Now you will get a question like in which situation I can use @future?

That is actually a good question

  1. When we need to do a web service callout after the DML operation.
  2. When you want to perform the calculations as soon as the resource are available.
  3. Before going to this user case can we solve the mixed DML operation problem by using this? The answer is yes, we can solve the mixed DML problem by using the @future annotation.

Enough to the theory now let’s take use case and see how can use the @future annotation.

Use case:

  1. Create a field Account “Number of Contacts” with data type Number. Update the field using @future annotation when the contact is created or Deleted.

Solution:

With the above use case what we need to do?

  1. We need to create a field on account
  2. We need to write a trigger on Contact and fire the trigger for insert and delete operations.
    Based on this information can you do of your own? If yes, that is great. Go ahead and do it. If you are
    new to apex no problem, you can check the code below.

Trigger on Contact: ContactTrigger

trigger ContactTrigger on Contact (after insert, after delete) {// After eventsif(Trigger.isafter) {if(Trigger.isInsert) {AccountProcessor.onAfterSave(Trigger.New);}if(Trigger.isDelete) {AccountProcessor.onAfterSave(Trigger.Old);}}}

Apex class: AccountProcessor

public with sharing class AccountProcessor {//== Method to execute on after Insert of contactpublic static void onAfterSave (List<Contact> contacts) {// Set to hold the account Id's from ContactSet<Id> acctIds = new Set<Id>();// Loop to iterate over the list of contactsfor(Contact con : contacts) {if(con.AccountId != null) {acctIds.add(con.AccountId);}}if(acctIds.size() > 0 && acctIds != null) {updateAccount(acctIds);}}//== Method to update the account based on Number of contacts@future(callout=false)private static void updateAccount(Set<Id> accIds) {// Qeury to fetch the account records based on AccountId from contactList<Account> accnts = [SELECT ID, Name, Number_of_Contacts__c, (SELECT Id FROM Contacts)FROM AccountWHERE ID = :accIds];System.debug('query results : ' +accnts.size());// Loop to iterate over the list of account records from Query resultsfor(Account acc : accnts) {List<Contact> cons = acc.Contacts; // List to hold the contacts that related to accountacc.Number_of_Contacts__c = cons.size();System.debug('Account:'+ acc.Name + ' has ' + acc.Number_of_Contacts__c + ' Contact childs');}try {update accnts;} catch(DMLException e) {throw new stringException('Faile to update the accounts : '+e.getMessage());}}}

In that method we are preparing the set of Id’s why not list of Id’s? More than one contact will be related to the same account if you are doing the file loads right so set will hold the unique Id’s. If the set is not null, then we are going to perform the actual logic. Why we need to perform that check? Don’t worry I’ll explain why. Account Id is not a required field so we can create individual contacts and we can link them to the parent account later time. So, what if the whole file that we are using is not having single account Id.

Then do we need to query on account? No right, now you got it. In the downstream logic we are performing the query on account with the Id’s that we collected from the list of contacts and based on the account Id’s we are getting the up to time, wait what why not up to date? contacts and assigning that value to the account field after that perform the DML operation using try catch block
to handle the exceptions.

Things to Remember

Things to Remember when using @future annotation

  1. Future method should return void and it should be declared as static.
  2. Can we pass objects as a parameter to the future method? No, we cannot pass the objects (custom, standard) as parameter. We can only pass the Id’s as a parameter, primitive data type or collection of primitive data types as a parameter.
  3. Why we cannot pass the object (custom, standard) as a parameter? Remember we are working with asynchronous apex they will execute only when the resources are available so if we use the object as a parameter then the system will not hold the current data.
  4. Did future method execute in the same order they called? The answer is no, as they are not guaranteed to execute in the same order. So, can we call it a limitation? Yes, we can overcome this by using the queueable apex.
  5. Will future methods run concurrently which means updating the same record by 2 future methods at a same time from different sources or the same source? Yes, and which could result in locking the record. so, need to incredibly careful while dealing with future methods.
  6. Do I have to take any special care while writing the test class for future methods? Yes, you need to enclose the code between start and stop test methods.
  7. Can I use future method for bulk transactions? The answer will not be likeable, but it is good to avoid future and good to use batch processing.
  8. What is the limit on future calls per apex invocation? 50, additionally there are limits base on the 24-hour time frame.
  9. Can we user future method in visual force controller constructors? The answer is no.
  10. Can I call a future method from another future method? No, you cannot call one future method from another future method.

Queueable Apex

Before jumping on to queueable apex lets try to remember some of the limitations that future method is having.

  1. Can we pass objects, apex types as a parameter to the future method? No, we cannot pass them as arguments. So, how can I do that?
  2. Can I monitory future jobs? No, it is a method that resides in an apex class and it will execute whenever the resources are available. So, how can we resolve this? Is there any way that I can implement asynchronous jobs and monitor them?
  3. Can we implement chain process? Forget with future because we cannot call future method from another future method. So, how can we resolve this?

The only solution to the above 3 problems is implementing the queueable apex. What is queueable apex and how can me implement them. Oh! Wait too many questions.

Queueable apex is hybrid class. Why you are calling it as hybrid class? Yes, I mean to say it is designed in a way by combining the batch apex and future apex. So, that means do we have to again write the start, execute, and finish methods like the batch. As I said it is a combination not the exact replica. No, you don’t need to write start and finish methods. All you need is execute method. How cool it is right.

Use Case

You need insert a contact for each account for a specific state.

public class AddPrimaryContact implements Queueable {// Declaring the varibalesprivate Contact contact;private String state;//== Defualt constructor with parameters as account and state valuepublic AddPrimaryContact(Contact contactRecord, String stateValue) {this.contact = contactRecord;this.state = stateValue;}public void execute(QueueableContext context) {List<Account> accounts = getAccounts(state);// Condition to check for the List is emptyif(accounts.size() > 0) {List<Contact> updateContacts = new List<Contact>();// Loop to iterate over the list of Accountsfor(Account account : accounts) {Contact con = new Contact();con.AccountId = account.Id;updateContacts.add(con);}// Condition to check if the contact list is emptyif(updateContacts.size() > 0) {Database.SaveResult[] results = Database.insert(updateContacts, false);// Loop to iterate over the DML Operation resultsfor(Database.SaveResult result : results) {if(result.isSuccess()) {System.debug('Successufully inserted the contact. Contact Id : ' + result.getId());} else {for(Database.Error error : result.getErrors()) {System.debug('Contact failed to Insert with error code : '+ error.getStatusCode() +' with error Message : ' +error.getMessage());}}}}}}// Method to fetch the List of account records based on the State value.public static List<Account> getAccounts(string state) {return [SELECT ID, Name,(SELECT Id, FirstName, LastName FROM Contacts)FROM AccountWHERE BillingState = :state];}}

In the class we are passing the parameters as contact and the state value. The default constructor will receive it and we created 2 global variables one for contact and the other for the state value to hold and to use them in our downstream logic. The execute method is first doing a query on account object and bringing all the records that matches with the state value then we are checking if there are any query results if so then we are iterating over the query results and then we are creating the new contact for those accounts.

Here we used the Database.saveResult to do the DML operation. What if I ask you to send an email to Admin for the failed Accounts there you can use the chain process to send the email to admins. Let us try for yourself as an assignment.

Limitations for queueable apex

let’s look at what are limitations for queueable apex.

  1. How many jobs can we schedule from queueable apex? Only one.
  2. Can I chain the jobs from test class? No, you cannot do that unless you want to end up with errors.
  3. How many jobs I can add by using system.enqueueJob for a single transaction? 50
  4. What is the stack depth for chaining the jobs? In developer edition it is limited to 5 including the parent job.
  5. Which one is easy to modify queueable or future? The answer is future as it resides in the apex class and easy to remove the annotation “@future”. Does it impact the test class no it won’t impact the test class? How cool it is right switching between synchronous to asynchronous and vice versa

Generic Approach to Salesforce Queueable

Future Vs queueable apex

Now let’s look at the main differences between Future and queueable apex

FUTURE APEXQUEUEABLE APEX
It is annotation based so we can use the same apex class to write the future method. Syntax: @futureIt is a class which implements’ queueable interface. Syntax: public class CLASS_NAME implements Queueable{}
We cannot monitor the jobsWe can monitor the jobs based on the job Id.
we cannot call a future from another future or batch apex. The limit on future method for single apex invocation is 50.We can chain the Queueable jobs and the stack depth in developer org is 5 and in enterprise edition you can chain 50 jobs.
Future method supports only primitive datatypesQueueable supports both primitive and non-primitive data types.

Future Vs Queueable Apex (2)

Conclusion

Which one to prefer for satisfying your logic? Based on this explanation I believe you will be in good shape to identify which one to choose.

Further Learning

  • Asynchronous Apex
  • Batch Job and Scheduler.
Future Vs Queueable Apex (2024)

FAQs

What is the advantage of queueable apex over future methods? ›

Queueable Apex provides several advantages over future methods and batch Apex. It supports higher limits, enables chaining of jobs, and accepts complex data types as parameters, which makes it more flexible and powerful for handling large, complex jobs.

What are the limitations of Queueable apex? ›

Limitations of Queueable Apex

Queueable can't handle millions of records in one job. Only one job can be scheduled at a time. In the developer edition stack depth for chaining the jobs is limited to 5 including the parent job.

What are the limitations of future methods? ›

Future methods are subject to asynchronous execution limits, which include a limit of 50 calls per transaction and a maximum timeout of 60 seconds. Queueable methods have higher execution limits than future methods. The maximum timeout for a queueable method is 60 minutes.

What is the difference between Queueable and apex? ›

The difference between queueable and Batch Apex (which all belong to asynchronous Apex), is that you would use Batch Apex whenever you are processing a larger number of records compared to queueable. Batch Apex jobs are limited to five tasks running simultaneously, whereas queueable jobs can run up to 100!

What are the limitations of the future method in Salesforce? ›

The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types; future methods can't take objects as arguments. Future methods won't necessarily execute in the same order they are called.

What are the limitations of future apex? ›

we cannot call a future from another future or batch apex. The limit on future method for single apex invocation is 50. We can chain the Queueable jobs and the stack depth in developer org is 5 and in enterprise edition you can chain 50 jobs. Queueable supports both primitive and non-primitive data types.

What are the advantages of Queueable apex? ›

Benefits of Queueable Apex:
  • Queueable apex supports the Non-primitive type member variables, such as SObject or custom apex types.
  • System. enqueueJob method returns the AsyncApexJob record id. Use this id to find your job and Monitor its progress.
  • You can chain one job with another job.

What is the difference between future and Queueable apex? ›

we cannot call a future from another future or batch apex. The limit on future method for single apex invocation is 50. We can chain the Queueable jobs and the stack depth in developer org is 5 and in enterprise edition you can chain 50 jobs. Queueable supports both primitive and non-primitive data types.

How many queueable jobs can run at a time? ›

According to the Salesforce governor limits, it is allowed to execute no more than 1 Queueable job from the contexts.

What are the advantages of future methods in Salesforce? ›

In Salesforce, Future Methods not only allow for asynchronous execution but also offer the capability to make callouts to external services. By leveraging the @future annotation with the additional parameter callout=true, developers can seamlessly integrate external services into their Salesforce applications.

Why future methods are void? ›

As they run at a future time from when they are called, they have nowhere to return a response and thus can only return a void type. Other than this and the fact that there is a limit as to how many future methods can be invoked at any one time, they look and behave like any other method.

What are the advantages and disadvantages of futures? ›

Future contracts have numerous advantages and disadvantages. The most prevalent benefits include simple pricing, high liquidity, and risk hedging. The primary disadvantages are having no influence over future events, price swings, and the possibility of asset price declines as the expiration date approaches.

When to use queueable apex? ›

As Salesforce developers, we use Batch Apex Class to process large numbers of records, while the Future method is used for executing long-running operations asynchronously. But when we need to have both the operations of the Batch and Future method, we should implement the Queueable Interface.

Can we make callouts from queueable apex? ›

Firstly, to execute queueable apex we need to implement the interface Queueable. Also, the method which is implementing the Queueable interface needs to be declared as public or global. If you want to allow callout then we also need to implement Database. AllowsCallouts.

Can we call the future method from queueable? ›

An alternative exists though: one can call a Queueable class method (which operates like a future method) solely from the finish method of a batch class. Then, you can implement a Queueable class that performs as a future method, which in turn can call another future method.

What is the difference between Queueable and future method? ›

@Future method gives us only one asynchronous transaction. Meanwhile, in Queueable we can split data into chunks and process them in multiple chained jobs. Critical operations, thanks to Finalizer we can reschedule a job, even if we got Limits exception.

What is the difference between batch future and Queueable apex in Salesforce? ›

- Batch Apex is more suitable for moderate to large database queries, while Queueable Apex is better for smaller increments of work executed more quickly. - If your requirement involves both batch and future methods or requires chaining multiple jobs, Queueable Apex is the better choice.

Can we call a future method from queueable apex? ›

Use Queueable Apex for Chaining Asynchronous Calls

As a workaround, you can use Queueable Apex to chain asynchronous calls. Queueable Apex can be used in place of future methods when you need to chain jobs (call another job from a job), and they can also be called from batch classes.

Top Articles
Latest Posts
Article information

Author: Nathanial Hackett

Last Updated:

Views: 6313

Rating: 4.1 / 5 (72 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Nathanial Hackett

Birthday: 1997-10-09

Address: Apt. 935 264 Abshire Canyon, South Nerissachester, NM 01800

Phone: +9752624861224

Job: Forward Technology Assistant

Hobby: Listening to music, Shopping, Vacation, Baton twirling, Flower arranging, Blacksmithing, Do it yourself

Introduction: My name is Nathanial Hackett, I am a lovely, curious, smiling, lively, thoughtful, courageous, lively person who loves writing and wants to share my knowledge and understanding with you.