Skip to main content

SF-0348 · Concept · Easy

What is a future method?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026 · Updated for Spring '26

A future method is a static Apex method annotated with @future. When the calling code reaches the method, Salesforce queues the invocation and returns immediately — the method body runs later, in a separate transaction, on the platform’s async thread pool. It’s the original async mechanism in Apex, designed for fire-and-forget tasks like callouts from triggers.

Anatomy

public class StripeService {
    @future(callout=true)
    public static void pushAccountIds(Set<Id> accountIds) {
        List<Account> accs = [SELECT Id, Name FROM Account WHERE Id IN :accountIds];
        for (Account a : accs) {
            HttpRequest req = new HttpRequest();
            req.setEndpoint('callout:Stripe/v1/customers');
            req.setMethod('POST');
            new Http().send(req);
        }
    }
}

Three rules baked into that signature:

  1. static@future methods must be static. They run without an instance.
  2. void return — there’s no caller to receive a return value. The method is fire-and-forget.
  3. (callout=true) if needed — if the method makes HTTP callouts, declare it. Without the flag, callouts throw.

Parameter restrictions

Future methods accept only primitive types, IDs, and collections of primitives. They cannot accept sObject types (no Account or List<Opportunity> parameters). Pass an Id or Set<Id> and re-query inside the method.

The reason is staleness: the future method runs after the calling transaction commits, possibly minutes later. An sObject parameter would be a snapshot from the past. Re-querying ensures you see the current database state.

When the method actually runs

  1. The calling transaction reaches the @future call.
  2. The platform queues the invocation. The calling code continues.
  3. Caller’s transaction commits.
  4. The future method dequeues — usually within seconds, sometimes longer under load.
  5. The method runs as a separate transaction with its own governor limits.

There’s no SLA on how soon a queued future runs. Plan for eventual, not immediate.

What it doesn’t do

@future was deliberately minimal. Compared to Queueable, it lacks:

Feature@futureQueueable
Accepts complex types (sObject, custom classes)NoYes
Returns a JobIdNoYes
Can chain another async jobNoYes
Monitorable in Apex Jobs UILimitedYes
Callouts supportedYes (with annotation)Yes (with interface)

For a new project in 2026, Queueable is the default choice. @future survives in legacy code and one-line use cases where its limitations don’t matter.

Limits

  • Maximum 50 future invocations per transaction.
  • Maximum 250,000 future invocations per 24 hours, or the equivalent based on org licenses (whichever is greater).
  • A future method cannot call another future method. (No @future-to-@future chaining.)
  • A future method cannot be called from a Batch Apex job. (Use Queueable from Batch instead.)

Common interview follow-ups

  • Can a future method return a value? — No, return type must be void.
  • Can I pass an sObject to @future? — No. Pass Ids; re-query inside.
  • What annotation lets @future make callouts?@future(callout=true).
  • When was @future introduced and when did Queueable arrive?@future has been in Apex since the early days; Queueable was added in Winter ‘15 to address @future’s limitations.

Verified against: Apex Developer Guide — Future Methods. Last reviewed 2026-05-17.