In Salesforce, executing long-running or resource-intensive operations synchronously can lead to governor limit issues. To handle such scenarios, Apex provides @future methods for asynchronous processing. These methods allow execution to be deferred to a later time, freeing up system resources and improving performance.
In this blog post, we’ll chat about using them, their advantages, best practices, and real-world examples.
What Are Apex Future Methods?
Future methods enable Apex code to execute asynchronously in a separate thread at a later time. This is useful when:
- Performing callouts to external web services.
- Processing large datasets that would exceed synchronous limits.
- Avoiding mixed DML operation errors.
Syntax:
@future
public static void someFutureMethod() {
// Asynchronous logic here
}
Key Features of Future Methods
- Run asynchronously: The method executes in the background, outside the context of the transaction that invoked it.
- No return values: Future methods cannot return values or accept sObjects as parameters.
- Allow callouts: Adding
@future(callout=true)allows web service callouts from a future method. - Governor limits apply per execution: Limits are reset for each asynchronous transaction.
How to Use Future Methods
Example 1: Performing an Asynchronous Update
Updating a large number of records asynchronously to avoid hitting limits:
public class FutureExample {
@future
public static void updateContacts(List<Id> contactIds) {
List<Contact> contactsToUpdate = [SELECT Id, LastName FROM Contact WHERE Id IN :contactIds];
for (Contact c : contactsToUpdate) {
c.LastName = 'Updated';
}
update contactsToUpdate;
}
}
Usage:
List<Id> contactIds = new List<Id>{'003XXXXXXXXXXXX', '003YYYYYYYYYYYY'};
FutureExample.updateContacts(contactIds);
Example 2: Making a Callout from a Future Method
Apex restricts callouts in synchronous transactions. Using a future method allows us to perform API requests:
public class CalloutExample {
@future(callout=true)
public static void makeCallout() {
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://api.onlyanexample.com/data');
request.setMethod('GET');
HttpResponse response = http.send(request);
System.debug(response.getBody());
}
}
Usage:
CalloutExample.makeCallout();
Example 3: Avoiding Mixed DML Errors
Salesforce prevents DML operations on setup and non-setup objects in the same transaction. Future methods help work around this.
public class MixedDMLExample {
@future
public static void updateUserRole(Id userId) {
User u = [SELECT Id, RoleId FROM User WHERE Id = :userId];
u.RoleId = '00EXXXXXXXXXXXX';
update u;
}
}
If this method were executed synchronously alongside inserting a custom object record, it would trigger a MIXED_DML_OPERATION error. Running it asynchronously prevents that.
Best Practices for Using Future Methods
- Limit the number of future calls: Each transaction can invoke a maximum of 50 future methods.
- Use
@futuresparingly: Consider using Queueable Apex for better control and chaining. - Avoid passing large data sets: Future methods have limits on parameter size.
- Monitor execution: Use the Apex Jobs page in setup to track execution status.
- Ensure Idempotency: Avoid duplicate processing if a future method is triggered multiple times.
Future Methods vs. Queueable Apex
In the next blog post we will talk about Queueable Apex, a more advanced form of asynchronous processing in Salesforce. Here is a comparison chart showing what you can do with both forms of transactions.
| Feature | Future Methods | Queueable Apex |
|---|---|---|
| Return Values | ❌ No | ✅ Yes (via chaining) |
| Supports Callouts | ✅ Yes | ✅ Yes |
| Supports Chaining | ❌ No | ✅ Yes |
| Allows Complex Logic | ❌ Limited | ✅ More Control |
For better flexibility and chaining, Queueable Apex is preferred over future methods in most cases.
Conclusion
Future methods provide a lightweight, asynchronous way to handle resource-intensive operations in Apex. However, they should be used carefully to avoid exceeding limits. While still useful, Queueable Apex is often a better alternative due to its ability to return values and chain jobs.
Have any questions? Drop them in the comments below!

We would love to hear your comments!