Future Methods in Salesforce (@future)

Future Methods in Salesforce (@future)

Future Methods in Salesforce (@future) | CertifySF

Future Methods in Salesforce (@future)

The oldest and simplest way to push Apex work into its own thread — what @future can do, the rules it enforces, and the point where Queueable takes over.

Apex Asynchronous Apex Verified: Winter '27 ~6 min read
The Brief

A future method is an Apex method annotated with @future that runs asynchronously in its own thread when Salesforce has resources free. It must be static, return void, and accept only primitive arguments. You use it to make callouts from triggers, dodge the mixed-DML error, and gain higher governor limits — without blocking the current transaction.

What @future Does and Why It Exists

Synchronous Apex runs on one thread and waits for every operation to finish before returning. That is fine until you hit something slow or restricted — a callout to an external system, or a mix of object types that Salesforce refuses to commit together. Future methods solve this by handing the work off to a separate, asynchronous thread that executes later, when the platform has capacity.

Marking a method with the @future annotation tells Salesforce to queue it rather than run it inline. The calling transaction finishes immediately; the future job runs on its own, in a fresh execution context with its own — and in several cases higher — governor limits. Because it is decoupled, a future method fits naturally after a trigger fires or after a synchronous DML operation completes. For the wider picture of where this sits among Batch, Queueable, and Scheduled Apex, see the complete guide to asynchronous Apex.

The Rules for Writing a Future Method

Salesforce enforces a strict signature, spelled out in the official Apex future methods reference. A future method must be static, must return void, and its parameters must be primitive data types, arrays of primitives, or collections of primitives. It cannot accept sObjects or objects as arguments. To make a callout from a future method, you also add callout=true to the annotation — the default is callout=false, which blocks callouts.

public with sharing class AccountSyncService {
@future(callout=true)
public static void syncToExternal(Set<Id> accountIds) {
// Requery for the latest data — you passed IDs, not sObjects
List<Account> accts = [
SELECT Id, Name, Industry FROM Account
WHERE Id IN :accountIds WITH USER_MODE
];
// ...build the request and call the external service
}
}

The no-sObject rule is not arbitrary. An sObject can change between the moment you enqueue the future call and the moment it actually runs. If the method held a stale copy, it could overwrite fresh data on save. The fix is the pattern above: pass a Set<Id> or List<Id>, then requery inside the method so you always work with the current record state.

Admin Tip

A trigger cannot make a synchronous callout. Wrapping the callout in an @future(callout=true) method is the classic way to call an external service from a trigger without blocking the record save.

Future Method Limits You Can't Ignore

Future methods trade convenience for constraints. The ones that trip up developers — and show up on exams — are less about the annotation and more about how the async queue behaves, as detailed in Salesforce's execution governors and limits.

ConstraintWhat it means
50 per transactionA single Apex transaction can enqueue up to 50 future calls.
No chainingA future method cannot call another future method.
Not from BatchYou cannot invoke a future method from a Batch Apex execute context.
No job IDNothing is returned when you call it, so you cannot monitor or track completion the way you can with Queueable.
Rollback drops itFuture jobs queued by a transaction are not processed if that transaction rolls back.
24-hour org cap250,000 executions, or user licenses × 200, whichever is greater — shared across all asynchronous Apex.

That 24-hour ceiling is org-wide and pooled: Batch Apex, Queueable Apex, Scheduled Apex, and future methods all draw from the same allowance. High-volume future traffic can starve your other async processes, which is why Salesforce advises using Batch Apex when you need to process large numbers of records rather than fanning out thousands of future calls.

Exam Alert

Two facts get tested repeatedly: a future method can't call another future method, and you can't pass an sObject to one (only primitives, arrays, or collections of primitives). If a scenario needs chaining or wants to hand off a full record, the answer is Queueable, not @future.

The Classic Use Case: Escaping the Mixed DML Error

Salesforce blocks a single transaction from committing changes to certain setup objects (such as User, UserRole, Group, and GroupMember) alongside non-setup objects (such as Account or Contact). Attempt both in one transaction and you get a MIXED_DML_OPERATION error.

A future method is the standard escape hatch. Because it runs in a separate transaction, moving one side of the DML — typically the setup-object work, like assigning a role to a user — into a future method isolates it from the non-setup DML. Each transaction now touches only one category, and the error disappears. Where this fits in the broader trigger-and-save sequence is covered in the Salesforce Apex order of execution.

When to Use Queueable Instead

Salesforce now recommends Queueable Apex over future methods for most new development. Queueable covers the same use cases and adds what @future lacks: a job ID you can monitor, support for non-primitive types (including sObjects), and job chaining for sequential async steps. It also uses a cleaner interface-based syntax instead of a bare annotation.

Key Concept

Reach for @future when the task is genuinely fire-and-forget — a single short callout or a quick mixed-DML isolation. The moment you need to pass a record, chain to a follow-up job, or track the result, Queueable is the better tool. For the full comparison across all four async mechanisms, work through the asynchronous Apex guide.

Future methods are not deprecated, and plenty of production orgs still use them for exactly the narrow jobs they were built for. But when you are choosing a tool for new async work, treat @future as the minimalist option and Queueable as the default — and use Batch Apex when the volume of records, not the type of work, is the real problem.

Fast Exam Recall

  1. Signature@future methods are static, return void, and take only primitives, arrays of primitives, or collections of primitives.
  2. No sObjects — pass IDs and requery inside the method; sObjects could go stale between call and execution.
  3. Callouts — add callout=true to allow callouts; the default blocks them.
  4. Can't chain — a future method can't call another future method, and can't be invoked from a Batch execute context.
  5. Async cap — 250,000 or licenses × 200 per 24 hours, shared across Batch, Queueable, Scheduled, and future.

Test Your Knowledge

Async Apex is a high-yield topic for developer certifications. Sharpen it with scenario-based practice questions.

Browse the Salesforce certification catalog

Verified against the official Salesforce Winter '27 Apex Developer Guide (Future Methods, Asynchronous Apex, and Execution Governors & Limits). Study smarter at CertifySF.com.

Shopping Cart