Future Methods in Salesforce

Future Methods in Salesforce @future

Future Methods in Salesforce using @future annotation

A future method runs in the background, asynchronously. You can call a future method for executing long-running operations, such as callouts to external Web services or any operation you’d like to run in its own thread, on its own time. You can also use future methods to isolate DML operations on different sObject types to prevent the mixed DML error. Each future method is queued and executes when system resources become available. That way, the execution of your code doesn’t have to wait for the completion of a long-running operation. A benefit of using future methods is that some governor limits are higher, such as SOQL query limits and heap size limits.

Future Methods in Salesforce

Future method syntax

global class FutureClass {
    @future
    public static void myFutureMethod() {   
         // Perform some operations
    }
}
  • Use @future annotation before the method declaration.
  • Future methods must be static methods, and can only return a void type.
  • The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types.
  • Future methods can’t take standard or custom objects as arguments.
  • A common pattern is to pass the method a list of record IDs that you want to process asynchronously.
    global class FutureMethodRecordProcessing {
        @future
        public static void processRecords(List<ID> recordIds){   
    	// Get those records based on the IDs
    	List<Account> accts = [SELECT Name FROM Account WHERE Id IN :recordIds];
    	// Process records
        }
    }
    

Future method callouts using @future(callout=true)

To allow callout from the future method annotation needs an extra parameter (callout=true) to indicate that callouts are allowed. Here is example

global class FutureMethodExample {
    @future(callout=true)
    public static void getStockQuotes(String acctName){
    	// Perform a callout to an external service
    }
}

Test Class for Future Methods

To test methods defined with the future annotation, call the class containing the method in a startTest(), stopTest() code block. All asynchronous calls made after the startTest method are collected by the system. When stopTest is executed, all asynchronous processes are run synchronously.

@isTest
private class MixedDMLFutureTest {
    @isTest static void test1() {
        User thisUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()];
       // System.runAs() allows mixed DML operations in test context
        System.runAs(thisUser) {
            // startTest/stopTest block to run future method synchronously
            Test.startTest();        
            MixedDMLFuture.useFutureMethod();
            Test.stopTest();
        }
        // The future method will run after Test.stopTest();
    
        // Verify account is inserted
        Account[] accts = [SELECT Id from Account WHERE Name='Acme'];
        System.assertEquals(1, accts.size());
        // Verify user is inserted
        User[] users = [SELECT Id from User where username='mruiz@awcomputing.com'];
        System.assertEquals(1, users.size());
    }
}

Future Method Performance Best Practices

Salesforce uses a queue-based framework to handle asynchronous processes from such sources as future methods and batch Apex. This queue is used to balance request workload across organizations. Use the following best practices to ensure your organization is efficiently using the queue for your asynchronous processes.

  • Avoid adding large numbers of future methods to the asynchronous queue, if possible. If more than 2,000 unprocessed requests from a single organization are in the queue, any additional requests from the same organization will be delayed while the queue handles requests from other organizations.
  • Ensure that future methods execute as fast as possible. To ensure fast execution of batch jobs, minimize Web service callout times and tune queries used in your future methods. The longer the future method executes, the more likely other queued requests are delayed when there are a large number of requests in the queue.
  • Test your future methods at scale. Where possible, test using an environment that generates the maximum number of future methods you’d expect to handle. This helps determine if delays will occur.
  • Consider using batch Apex instead of future methods to process large numbers of records.

 

For more details please refer to official link

To define a future method, simply annotate it with the future annotation, as follows.

Permanent link to this article: https://www.sfdcpoint.com/salesforce/future-methods-in-salesforce/

6 comments

Skip to comment form

    • SANdy on May 9, 2020 at 4:04 am
    • Reply

    Hi Ankush,

    Thanks for Nice Article.
    So for long running callout can we use future method if we are getting TimeOut error while doing a callout?
    Will it solve the error?
    And in which cases we should go for continuation class or Future for long running callout.

    1. We should go for the future, when we don’t want to see an immediate result. You can also set request timeout limit
      request.setTimeout(120000);

    • Deepali Kulkarni on August 29, 2020 at 3:15 pm
    • Reply

    Hi Ankush,

    This article is very helpful, thank you for sharing it.
    One question – Can we call @future annotation method inside @future method?

    1. No, you can not.
      You can use queueable for that and chain jobs
      https://www.sfdcpoint.com/salesforce/queueable-apex-salesforce/

    • rohit sandawa on September 1, 2020 at 11:27 am
    • Reply

    very helpful article .
    can we call other future method from one future method ?

      • Pavan on October 1, 2022 at 1:47 pm
      • Reply

      No we cannot call one future method from other future method

Leave a Reply

Your email address will not be published.