Skip to main content

SF-0362 · Concept · Medium

What are some limitations of future methods?

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

@future was Apex’s first async mechanism and the design has aged. Most of its limitations are why Queueable was introduced. Knowing the full list is interview territory.

The full list

LimitationDetail
Void return onlyMust return void. No way to receive a result back.
Static methods only@future must be applied to a static method.
Primitive args onlyAccepts primitives, Ids, and collections of primitives. No sObjects, no custom classes.
No chainingA future method cannot call another @future method.
No invocation from BatchBatch jobs cannot call @future methods.
50 invocations per transactionHard cap on how many @future calls a single transaction can queue.
Daily org-wide limitUp to 250,000 async invocations per 24 hours (or 200 × org licenses, whichever is greater).
No JobId monitoring@future returns nothing. The AsyncApexJob row exists, but you have no JobId from the call site.
No callouts without annotationMust declare @future(callout=true) for HTTP callouts.
Callout time limitMaximum 120 seconds total for callouts inside the method.
Not testable without Test.startTestFuture invocations run synchronously between Test.startTest() and Test.stopTest() — outside that block they don’t run during a test.

The “no chaining” rule in practice

public class FutureChainTest {
    @future
    public static void first() {
        second(); // throws System.AsyncException
    }
    @future
    public static void second() { /* never runs */ }
}

The platform throws AsyncException: Future method cannot be called from a future or batch method. The fix is Queueable, which can call other Queueables.

The 50-per-transaction limit, explained

If a single transaction calls 51 @future methods (even different methods), the 51st throws LimitException: Too many future calls: 50. Bulkify by passing a Set<Id> to one method invocation rather than calling per record.

// BAD
for (Account a : Trigger.new) {
    StripeService.push(a.Id); // 200 calls if Trigger.new has 200 records
}

// GOOD
StripeService.push(Trigger.newMap.keySet()); // 1 call

Why this matters for the interview

When the interviewer asks “what are the limitations of future methods?”, they’re often setting up the follow-up “so what would you use instead?” The answer is Queueable, and the reasons map one-to-one to the limitations above.

Limitation of @futureQueueable equivalent
No complex argsAccepts any serializable type
No chainingSystem.enqueueJob from inside execute() chains the next job
No JobIdSystem.enqueueJob returns the JobId
No monitoringTrack via AsyncApexJob SOQL on JobId

Common interview follow-ups

  • Can @future be called from a Schedulable? — Yes. Schedulable → @future is allowed.
  • Can @future be called from a Queueable? — Yes. Queueable → @future is allowed. The block is @future@future and Batch → @future.
  • What’s the workaround for “future from future”? — Replace the inner future with a Queueable, or convert the whole flow to Queueable chaining.

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