Share Your Experience With Others

Interview Preparation : Asynchronous Apex : Interview Questions

What Is Asynchronous Apex and Why Do We Need It?

Asynchronous Apex refers to code that executes in the background, separate from the main processing thread. It is essential for handling resource-intensive, long-running, or bulk operations without impacting user experience or running into Salesforce governor limits. Asynchronous processing lets users perform large data operations, callouts to external services, or schedule jobs for off-peak hours.

Key Reasons to Use Asynchronous Apex:

  • Avoids hitting Salesforce governor limits (memory, CPU, DML)
  • Improves app performance and responsiveness by delegating work to background processes
  • Enables the handling of large data volumes and complex calculations
  • Supports processes like scheduled reports, data cleansing, and external API callouts

Types of Asynchronous Apex

TypeWhen to UseCan Chain/Call Each Other?
Future MethodSimple background tasks, HTTP callouts, sending emails, updates not requiring complex controlCan call another future: No*
Batch ApexBulk data processing and long-running jobs (thousands/millions of records), bulk data cleansing or migrationCan chain batches: Yes
Queueable ApexTasks needing complex data types, dependency control, or job chainingCan chain/call queueable: Yes
Schedulable ApexAutomate processes on a schedule (e.g., nightly updates), run batch/queueable jobs periodicallyCan start batch/queueable

*Future methods cannot invoke other future methods directly. Batch, Queueable, and Schedulable can call or chain each other, usually through job submission APIs or by enqueuing jobs.

Explanation of Each Type

Future Method

  • What: Runs methods asynchronously using the @future annotation.
  • When to Use: For simple jobs (callouts, email, lightweight updates) that can run in parallel and don’t need complex processing or return values.
  • Limitations: Cannot return results or be directly chained, can’t be called from triggers that update related records extensively, not for heavy bulk processing.

Example Use Case: Update an external system after a record changes, send mass emails, or trigger an external API without holding up user actions.

Batch Apex

  • What: Divides large record sets into manageable chunks and processes them separately in batches.
  • When to Use: For operations involving thousands to millions of records (data migrations, cleansing, recalculations, mass updates).
  • Features: Can handle bulk records, manage errors at the record level, and be scheduled/chained.
  • Limitations: More setup code required, not for immediate short tasks.

Example Use Case: Standardizing address formats for millions of customer records.

Queueable Apex

  • What: Similar to future methods but supports job chaining, complex objects as parameters, and easier monitoring.
  • When to Use: When you need to pass more complex data, chain jobs, or handle post-processing tasks. Good for bulk jobs that are smaller than batch jobs but more complex than future jobs.
  • Features: Can chain multiple jobs, better monitoring/debugging, supports job dependencies.

Example Use Case: Send email reminders, then update related tasks, then notify users in sequence.

Schedulable Apex

  • What: Allows scheduling of Apex code execution based on CRON expressions or preset times.
  • When to Use: For jobs needing periodic runs (daily, hourly, custom schedules), like scheduled reporting, regular data cleanup, or recurring integration points.
  • Features: Uses the Schedulable interface; can invoke batch or queueable jobs.

Example Use Case: Nightly data integrity checks or monthly data archiving.

Tracking Failing and Successful Records

For bulk asynchronous processes (especially Batch Apex), Salesforce provides ways to count and handle successful and failed records:

  • Database.Stateful Interface: Used in Batch Apex to keep running totals of success/failure across different batches.
  • Processing Results: Use Database.SaveResult for each batch or transaction to check if individual records succeeded (isSuccess()) or failed, and increment counters accordingly.
  • Error Logging: Failed record IDs and error messages can be logged or emailed for tracking and re-processing if needed.
  • AllOrNone Flag: In DML operations, setting allOrNone = false allows some records to succeed even if others fail, making it easier to track partial successes.

Sample Mechanism for Success/Failure Counting (Batch Apex)

textpublic class ExampleBatch implements Database.Batchable<SObject>, Database.Stateful {
    public Integer successCount = 0;
    public Integer failureCount = 0;

    public void execute(Database.BatchableContext bc, List<Account> scope) {
        Database.SaveResult[] results = Database.update(scope, false);
        for(Database.SaveResult res : results) {
            if(res.isSuccess()) successCount++;
            else failureCount++;
        }
    }

    // Other required methods: start, finish
}

Interview Questions

1. What is Asynchronous Apex? Why use it over synchronous Apex?

Asynchronous Apex enables you to run code in the background, outside of the main execution thread, without blocking user actions. It is essential when performing operations that:

  • Take a long time (like bulk updates)
  • Must avoid hitting governor limits during synchronous processing
  • Should not make users wait for completion

Benefits over synchronous Apex:

  • Handles time-consuming operations without making users wait
  • Processes large data volumes efficiently by chunking operations
  • Provides higher governor limits for some asynchronous processes (like batch jobs)
  • Solves mixed DML, callout-from-trigger, and other limitations of synchronous operations

2. Differences: Future, Batch, Queueable, and Schedulable Apex

FeatureFuture MethodsQueueable ApexBatch ApexSchedulable Apex
Use CaseSimple, quick async tasksComplex tasks, job chainingProcessing millions of recordsRecurring tasks (scheduled jobs)
Data HandlingPrimitives onlyPrimitives, Objects, CollectionssObject/Data in chunksAnything
ChainingNot supportedSupported (one after another)Can chain with finish() methodCan schedule any class
MonitoringCannot directly monitor or queryCan monitor with job IDFull monitoring via AsyncApexJobCan track scheduled jobs
Batch/ParallelSingle contextRuns in separate threadData split into manageable batchesRuns as a scheduled job
Typical Limits50 calls per transactionSimilar to future but more flexible50M records per job, 5 concurrent jobsSimilar to Queueable/Future/Batch
ExampleSend email, callout, loggingChained data sync, long opsLead cleanup, data correction jobsNightly cleanup, scheduled reporting

3. How would you process millions of records in Salesforce?

  • Use Batch Apex as it processes large datasets efficiently by dividing data into small, manageable chunks (batches).
  • Each batch executes independently, resetting governor limits for every batch.
  • Batch jobs can handle up to 50 million records per execution.
  • Queueable Apex—while flexible—should be reserved for less massive volumes.

4. Can Future methods call other asynchronous Apex methods?

  • No, you cannot call a future method from another future method.
  • You cannot directly invoke a future method from Batch Apex or other async contexts either.
  • However, a Future method can invoke a Queueable Apex job if you need chaining.
  • As of 2025, only certain special orgs with pilot features may support chained futures, but this is rare.

5. How do you track successful and failed records in a Batch Apex job?

  • Use the Database class with allOrNone=false. This returns a Database.SaveResult[] for each record.
  • You can iterate through the results, counting and storing successes and errors.
  • Keep a stateful variable to collect errors during execution.
  • In the finish() method, summarize results and, if needed, send notifications or write to a custom log object.

6. When would you prefer Queueable over Future methods?

Prefer Queueable Apex when:

  • You need to chain jobs (i.e., run one async job after another)
  • You want to pass complex data types (like sObjects or collections)
  • Job status tracking and monitoring is important
  • You require stateful processing across job executions

Use Future methods only for simple, one-off operations with primitive types where tracking isn’t needed.

7. Describe a scenario for using Scheduled Apex.

Scheduled Apex is perfect for:

  • Daily/weekly/monthly data cleanups
  • Sending out scheduled reports or notifications
  • Performing repeat integrations with external systems at a set time
  • Routine maintenance, such as recalculating fields or syncing data between orgs

You implement a class with the Schedulable interface and schedule it via the UI or programmatically with a cron expression.

8. How would you handle partial successes in a batch operation?

Two main methods:

  • Use the Database.method (like insertupdate) with allOrNone=false to allow for partial DML success.
  • Iterate through the returned array of Database.SaveResult, collecting errors, then log or alert as appropriate.
  • Use Database.Stateful to preserve state across batch executions and relay the summary at the end.

9. What are governor limits, and how does asynchronous Apex help address them?

Governor limits are runtime limits enforced by Salesforce to prevent overconsumption of resources (e.g., SOQL queries, DML rows).

  • In synchronous Apex, all processing shares a single execution context and its limits.
  • Asynchronous Apex (especially Batch and Queueable) increases limits or resets limits per batch/job.
  • Example: Batch Apex gets higher limits and a fresh set of governor restrictions for each execution chunk, enabling the processing of far more records safely.

10. How can jobs be chained or scheduled together in Salesforce?

  • Queueable Apex allows native chaining: Each queueable job can enqueue another queueable job at completion (single chain depth per job).
  • Batch Apex chaining: You can start a new batch from the finish() method of another.
  • Schedule recurring jobs: With Schedulable Apex (set with cron expressions), you can automate job execution.
  • Job orchestration: Use platform events, Async Apex patterns, or custom logic to sequence jobs as needed for advanced scenarios

11. What happens if a batch job fails midway?

  • If a batch Apex job fails during execution, only the current batch is affected—other batches can still proceed.
  • Failed records in a batch can be identified using the Database.SaveResult array.
  • Salesforce records errors and marks the job as “Failed” if critical errors occur, and you can view details in the Apex Jobs page.
  • To handle failures robustly, implement exception handling and use Database.Stateful to capture failed records for reporting or possible retry.

12. Can you send notifications after async jobs complete?

  • Yes, use the finish() method in Batch Apex or the end of a Queueable/Schedulable job to send emails, notifications, or platform events upon job completion.
  • For complex integrations, custom logic can notify users of success, failure, or partial successes.

13. How do you monitor the progress of async jobs?

  • Monitor jobs in Setup under “Apex Jobs.”
  • For Batch and Queueable Apex, job IDs allow status querying via SOQL on AsyncApexJob objects.
  • Programmatically, you can fetch job status, number of processed/failed batches, and detailed logs.

14. Can governor limits still be reached in async jobs?

  • Yes, every batch or async execution gets its own governor limits.
  • Limits are generally higher for async compared to synchronous routines, but they are still enforced.
  • Example: Each batch execution in Batch Apex gets fresh SOQL and DML limits.

15. How do you use async apex for callouts from triggers?

  • Callouts are not allowed directly from triggers because triggers run synchronously.
  • Instead, enqueue a Future or Queueable Apex method that performs the callout after the trigger has finished execution.
  • Remember: Only one callout per Future method, but Queueable Apex can support multiple callouts.

16. What governor limits apply to each async type?

Async TypePer-Execution Limit Examples
Future50 calls per transaction, 10 callouts, 100 SOQL queries
Queueable50 jobs added to queue, 50 callouts, 100 SOQL queries
Batch Apex250,000 records returned in QueryLocator, 50 million records per run, 200 executions per 24 hours, 5 concurrent jobs
SchedulableFollows limits of invoked method
  • Check Salesforce documentation for current and detailed list of limits.

17. How do you debug issues in async jobs?

  • Use system debug logs filtered for “Apex Jobs.”
  • Log useful information inside try/catch blocks.
  • Use email or custom logging to record details on errors or partial successes.
  • For persistent issues, chain smaller batches or increase logging levels.

What is the maximum number of async jobs allowed concurrently?

  • Salesforce allows up to 5 concurrent batch jobs and up to 50 Queueable jobs added to the queue per transaction.
  • The org limit for total number of async jobs in the queue varies by edition and license.
  • Exceeding limits results in errors or jobs being delayed.

18. How do you pass parameters to scheduled jobs?

  • Implement the Schedulable interface with parameters passed in the execute() method (via custom fields or setup).
  • Use custom settings, custom objects, or static/class variables to hold state.
  • For Queueable and Batch, you can pass objects or record IDs through constructors.

19. How do you implement retry logic for failed records in async jobs?

  • Collect failed records in an array within the job.
  • After completion, re-process these records using another async job, or set a status for manual intervention.
  • For robust retry, schedule another Batch job on failed results via the finish() method.

20. Which async method is best for large file processing?

  • Use Batch Apex for large volumes and file processing, as it can handle millions of records and break processing into manageable chunks.
  • For file imports, process in batches through QueryLocator.
  • Queueable Apex can supplement for smaller, complex processing tasks.

21. Can Batch/Queueable jobs be aborted or paused once started?

  • Yes, jobs can be aborted (terminated) using the “Apex Jobs” page in Setup or via the System.abortJob(jobId) Apex method.
  • Pausing is not natively supported; you must design jobs for restart/resume by storing status in custom objects or fields.

Summary Table

FeatureUse Case ExampleCan Chain/Call Others?Failure/Success Tracking
Future MethodAPI callouts, mass emailsNoManual (try/catch)
Batch ApexData migration, cleansingYesDatabase.Stateful
Queueable ApexSequential tasks, complex dataYesCustom logic, try/catch
Schedulable ApexNightly jobs, periodic reportsYesN/A (calls others)

Why Can’t We Call Future Methods From Triggers (in All Cases)?

You can call a future method from a trigger, but with serious restrictions:

  • Governor Limit Constraints: When a trigger is run inside another asynchronous process (like Batch or another Future), Salesforce prohibits calling another future method. “Future method cannot be called from a future or batch method” error will occur if you attempt this. This is to prevent abuse and runaway asynchronous chains, which can overload platform resources.
  • Typical Scenario: If a trigger is fired during normal user operations, you can call a future method directly from that trigger. However, if the data changes come from a Batch or another asynchronous process, this will fail.

How One Async Option Calls Another (+ Code Examples)

Async TypeCan Call Future?Can Call Queueable?Can Call Batch?Can Call Schedulable?Notes
TriggerYes*YesYesYesFuture only if not already inside async context
Future MethodNoYes (with caveats)NoNoChaining not allowed for future-to-future, batch, or sched
Queueable ApexYes**YesNoNoCan queue other queueables; can call future if not in future already
Batch ApexNoYesYesNoCan’t call future directly, workaround via queueable
Schedulable ApexYesYesYesN/ACan invoke any async in execute()

* Subject to not being inside another async context
** Only if not violating async chain limits

1. Calling a Future Method From a Trigger

You can do this if the trigger is not being run from a batch or future context.

texttrigger OpportunityTrigger on Opportunity (after update) {
    Set<Id> oppIds = new Set<Id>();
    for(Opportunity opp: Trigger.new){
        if(opp.StageName == 'Closed Won'){
            oppIds.add(opp.Id);
        }
    }
    FutureMethodDemo.sendClosedWonEmail(oppIds);
}

public class FutureMethodDemo {
    @future
    public static void sendClosedWonEmail(Set<Id> oppIds){
        // background process (e.g., send emails)
    }
}

Use this pattern only when sure the trigger won’t be invoked by batch/future context.

2. Calling Future From Batch Apex (Not Allowed Directly)

Salesforce prohibits direct call to future methods from batch context. If you try, you’ll see:
“Future method cannot be called from a future or batch method”.

Workaround: Call a Queueable job from the batch, then invoke the future method from the queueable.

textpublic class MyBatch implements Database.Batchable<SObject> {
    public Database.QueryLocator start(Database.BatchableContext bc) {
        // your query
    }
    public void execute(Database.BatchableContext bc, List<SObject> scope) {
        System.enqueueJob(new MyQueueable(scope));
    }
    public void finish(Database.BatchableContext bc) { }
}

public class MyQueueable implements Queueable {
    List<SObject> records;
    public MyQueueable(List<SObject> records) {
        this.records = records;
    }
    public void execute(QueueableContext context) {
        FutureClass.process(records); // Now it's allowed
    }
}

public class FutureClass {
    @future
    public static void process(List<SObject> records) {
        // Do something asynchronously
    }
}
  • Batch calls Queueable, Queueable calls Future (never Batch→Future directly).

3. Calling Future From Queueable Apex

Permitted if the code is not already triggered by another future method.

textpublic class MyQueueable implements Queueable {
    public void execute(QueueableContext context) {
        FutureClass.someFutureWork(someId);
    }
}
// But you cannot call another queueable from within future, and async chain depth applies[11].

4. Calling Future From Schedulable Apex

Schedulable’s execute() runs in synchronous context, so you can directly call a future method:

textpublic class ScheduledJob implements Schedulable {
    public void execute(SchedulableContext sc) {
        FutureClass.scheduledTask();
    }
}
public class FutureClass {
    @future
    public static void scheduledTask() {
        // background logic
    }
}
  • Use this to schedule periodic async operations.

5. Triggering Other Async Types From Each Other

Future From Future: Not Allowed

text- Chaining future methods (future calling another future) is not supported[7][3].

– Queueable From Future: Possible but With Limits

You’re limited to one Queueable enqueued from any async/future context, else you'll get "Too many queueable jobs..." error[10].

Batch/Queueable/Schedulable can generally invoke Queueable or Batch (within limits).

Key Takeaways

  • Don’t call future methods in triggers if the trigger may be invoked as part of batch/future jobs.
  • To chain async logic, prefer Queueable Apex or link via supported patterns (Batch→Queueable→Future, etc.)
  • Check async chaining and depth limits to avoid system exceptions.
  • Use future when you need simple, one-step background logic; use queueable/batch for more complex dependency chains.

Summary Table:

You Are In…Can Call Future Directly?Workaround
Trigger (normal)YesN/A
Batch ApexNoBatch→Queueable→Future
Future MethodNoUse Queueable/Batch
QueueableYes (limited)Prefer chaining Queueables
SchedulableYesN/A

Monitoring Asynchronous Apex in Salesforce

Salesforce offers several ways to monitor and manage asynchronous execution, including Future Methods, Batch Apex, Queueable Apex, and Schedulable Apex. Below is an overview of how you can monitor and track each type.

1. General Asynchronous Monitoring

  • Apex Jobs Page:
    Navigate to Setup → type Jobs in the Quick Find box → select Apex Jobs.
    • This page lists all asynchronous Apex jobs, including status, submitted time, completion time, and any errors.
    • You can filter or search for specific jobs, see job types such as Future, Batch, or Queueable, and drill down for more details.
  • Apex Flex Queue:
    For Batch Apex jobs waiting to be processed, go to Apex Flex Queue under Jobs in Setup, which allows you to reprioritize pending jobs.

2. Monitoring Future Methods

  • Apex Jobs List:
    All executed future methods appear here. You can check job status and errors as you would for other jobs. Note that Future Methods do not return a Job ID when invoked.
  • SOQL Query:
    Query the AsyncApexJob object, filtering by fields such as MethodName or JobType = 'Future', to track or audit jobs programmatically.

3. Monitoring Batch Apex

  • Apex Jobs Page:
    Shows all submitted batch jobs, individual batch statuses, processed record count, and error messages per batch.
  • Batch Jobs Page:
    Accessible from a link at the top of the Apex Jobs list, focuses only on batch jobs and allows filtering by date or class.
  • Apex Flex Queue:
    View jobs waiting to run, their order, and reprioritize if needed.
  • Event Monitoring API:
    Leverage for real-time insights and troubleshooting. Advanced admins can use event logs for more granular tracking.
  • Custom Lightning Components:
    For user-friendly monitoring, build custom indicators using LWC and an Apex controller querying AsyncApexJob.

4. Monitoring Queueable Apex

  • Apex Jobs Page:
    Every queueable job appears here, with status, job ID, and error details.
  • Programmatic Monitoring:
    The System.enqueueJob() method returns a Job ID, which you can use in a SOQL query on AsyncApexJob for up-to-date status and error counts:textAsyncApexJob jobInfo = [SELECT Status, NumberOfErrors FROM AsyncApexJob WHERE Id = :jobID];
  • Chained Jobs:
    Each chained job is listed separately, so monitor each job’s ID in the queue.

5. Monitoring Schedulable Apex

  • Scheduled Jobs Page:
    In Setup, search for Scheduled Jobs. View all scheduled jobs with information like job name, job type, next scheduled run, and status.
  • Pause, Resume, or Delete:
    You can manage scheduled jobs directly from this UI.

Tips and Best Practices

  • Enable Debug Logs:
    For detailed execution tracing, set up debug logs for the running user. Helpful for troubleshooting job errors.
  • Custom Monitoring Objects:
    For advanced auditing, log async job results (IDs, status, error messages) in a custom object.
  • API Monitoring:
    Use SOQL and the Event Monitoring API for automated scripts or external dashboards.
  • Monitor Limits:
    Track your org’s asynchronous Apex consumption on the Apex Jobs Setup page to avoid hitting org limits.

Reference Table

Async OptionWhere to MonitorExtra Tools
Future MethodApex Jobs, SOQL on AsyncApexJobDebug Logs, Custom Logs
Batch ApexApex Jobs, Batch Jobs, Apex Flex QueueEvent Monitoring API, Custom LWC
Queueable ApexApex Jobs, SOQL on AsyncApexJobChained Job IDs
Schedulable ApexScheduled JobsApex Jobs (for execution), Pause/Resume/Delete

Leave a comment