Introduction
As Salesforce implementations grow, some operations become too long-running, high-volume, or integration-heavy to perform comfortably inside the initiating transaction. Asynchronous Apex lets us move that work into a separate transaction so the initiating transaction can complete without waiting for the background work. This post provides a single reference guide for Salesforce Async Apex Interview Questions: async processes, future methods, Queueable Apex, Batch Apex, and Scheduled Apex.
Interviewers lean on this topic heavily because it separates candidates who memorized syntax from candidates who understand why Salesforce provides different asynchronous mechanisms and when each one is appropriate.
What Is Async Apex?
Asynchronous Apex is code that Salesforce executes in a separate transaction from the transaction that initiated it. The application hands over the work to the platform, the platform queues it, and Salesforce executes it when resources are available. You shouldn’t design business logic around an exact start time unless the mechanism is specifically scheduled. The separate transaction gives the asynchronous execution its own governor-limit context. That makes async Apex useful for work that is long-running, needs to be decoupled from the initiating transaction, requires large-volume processing, or must be orchestrated independently.
Types of Async Apex
Salesforce supports four asynchronous execution mechanisms:
- Future Methods—It is a legacy/simple fire-and-forget asynchronous processing method. Future methods remain supported, but Salesforce recommends Queueable Apex for new production implementations when it can meet the requirement.
- Queueable Apex—It is the preferred general-purpose asynchronous mechanism for new Apex when you need complex parameters, job monitoring, chaining, or callouts.
- Batch Apex—built for processing large data volumes (thousands to millions of records) in manageable chunks.
- Scheduled Apex—runs any of the above on a recurring schedule, like a cron job.
Each one exists to solve a different shape of problem: small isolated tasks, complex chained logic, massive record volumes, or time-based automation.
Future vs Queueable vs Batch vs Scheduled
Comparison Table
| Feature | Future Method | Queueable Apex | Batch Apex | Scheduled Apex |
|---|---|---|---|---|
| Best for | Simple, fire-and-forget tasks (callouts, isolating DML) | Complex logic, chaining jobs, passing objects | Millions of records, bulk data operations | Running any job on a recurring schedule |
| Accepts non-primitive parameters (sObjects, custom objects) | No—primitives and collections of primitives only | Yes—including sObjects and custom Apex classes | Yes, via start() and execute scope. | It depends on the job it schedules |
| Job monitoring | Not trackable | Returns a job ID trackable via AsyncApexJob | Trackable via AsyncApexJob, plus Database.BatchableContext | Trackable via CronTrigger and CronJobDetail |
| Chaining | Not supported | Supported—one queueable can enqueue another | Not directly, but a batch’s finish() can enqueue another batch | Can invoke queueable or batchable jobs |
| Governor limit reset | New limits per future call | New limits per queueable execution | New limits per batch chunk (default 200 records) | New limits per scheduled execution |
| Callouts | Supported with @future(callout=true) | Supported by implementing Database.AllowsCallouts | Supported by implementing Database.AllowsCallouts | Not directly — must delegate to a batch job |
| Concurrent job limit | 50 future calls per Apex invocation (varies by context) | 50 queueable jobs per transaction (5 for child jobs from a batch/future) | 5 active batch jobs per org at a time | 100 scheduled jobs at a time |
| Introduced to replace | – | Future methods (recommended default going forward) | – | – |
Refer Guide: Avoid Batch Apex and Use Queueable Class
Basic Async Apex Interview Questions
Q1. What is Asynchronous Apex, and why does Salesforce need it?
Salesforce orgs store huge volumes of data, and that volume only grows over time. If you try to run a long or heavy operation synchronously, you risk hitting limit errors, heap size errors, or timeouts before the operation finishes. Asynchronous Apex avoids that by running the operation in a separate transaction, at a later time chosen by the platform, so it doesn’t block the user’s transaction or exhaust the current transaction’s limits.
Example: A “Recalculate All Prices” button that touches 50,000 opportunity line items would fail synchronously. Wrapping that logic in Batch Apex lets it run safely in chunks.
Q2. Where would you actually use Asynchronous Apex in a real project?
We can use async Apex any time when an operation is long-running, high-volume, or needs to happen outside the current transaction. Common real-world uses include:
- Sending emails or notifications after a record is saved
- Building complex reports or roll-up calculations in Apex
- Calling an external system for many records at once
- Scheduling a job to run at a fixed time, like a nightly cleanup
- Chaining Apex logic that includes an API call
- Recalculating sharing after a large ownership or hierarchy change
Q3. What are the practical benefits of asynchronous processing?
Async processing runs whenever the platform has spare capacity, so it never blocks a user from continuing their work. That gives you three concrete advantages:
- Better user experience—users aren’t stuck waiting for a long operation to finish.
- Higher limits — async transactions get more heap space and higher governor limits than synchronous ones.
- Better scalability — large or bulk operations can be broken into pieces instead of forcing everything through one transaction.
Q4. What are the four types of Asynchronous Apex?
Salesforce currently supports:
- Future Methods
- Queueable Apex
- Batch Apex
- Scheduled Apex
Each targets a different problem: simple background tasks, complex chained logic, large data volumes, and time-based execution. respectively.
Q5. How soon does an asynchronous job actually run after you enqueue it?
Async jobs sit behind real-time interactions (page loads, API calls) in priority, so the platform runs them whenever a processing slot becomes free. We cannot guarantee an exact start time—it could run within seconds, or it could take longer if the org’s async queue is busy. Salesforce, not our code, decides the exact execution moment.
Q6. Can you make a callout directly from a trigger?
No, not synchronously. A trigger runs inside the same database transaction as the DML that fired it, and holding that transaction open while waiting on an external system would risk timeouts and lock records for too long.
Instead, you delegate the callout to an async mechanism, typically a future method with callout=true or a Queueable class that implements Database.AllowsCallouts so the trigger’s transaction can commit immediately while the callout happens separately.
Refer Guide: Top Mistakes Developers Make in Salesforce Apex Triggers
Q7. Can a future method call another future method?
No. Salesforce blocks future methods from invoking other future methods. If you need to chain background logic, use Queueable Apex instead—a queueable job can enqueue another queueable job from inside execute(), which gives you controlled, trackable chaining that future methods were never designed to support.
Queueable Apex Interview Questions
Q8. What is Queueable Apex, and how is it different from a future method?
Queueable Apex is an interface (Queueable) that lets us run a unit of work asynchronously, similar to a future method, but with three big upgrades:
- It accepts non-primitive parameters like sObjects and custom classes;
- It returns a monitorable Job ID; and
- It supports chaining one job into the next.
Most architects treat Queueable Apex as the modern default over future methods for anything beyond a trivial callout.
Q9. How do you implement a basic Queueable class?
We implement the Queueable interface and put your logic inside the execute(QueueableContext context) method, then enqueue it with System.enqueueJob().
public class UpdateAccountRatings implements Queueable {
private List<Account> accounts;
public UpdateAccountRatings(List<Account> accounts) {
this.accounts = accounts;
}
public void execute(QueueableContext context) {
for (Account acc : accounts) {
acc.Rating = 'Hot';
}
update accounts;
}
}
// Enqueue it
System.enqueueJob(new UpdateAccountRatings(accountList));
Q10. Can you chain Queueable jobs, and are there limits on chaining?
Yes. From inside execute(), a queueable job can call System.enqueueJob() again to start the next job in the chain. From a synchronous transaction, you can enqueue up to 50 Queueable jobs. Once you are already in an asynchronous transaction, only one Queueable job can be enqueued from that transaction. Chaining is powerful, but treat it carefully—a long, unbounded chain can quietly turn into a runaway background process.
Q11. Can a Queueable Apex job make a callout?
Yes. The Queueable class must implement Database.AllowsCallouts. This is one reason Queueable Apex is a common choice for asynchronous integrations from triggers and other Apex transactions.
Q12. Can you call a Queueable job from inside Batch Apex?
Yes, but with a restriction: we can only call System.enqueueJob() once per execute() method inside a Database.Batchable class. Salesforce enforces this limit specifically to prevent a single batch
from spawning an explosive number of queueable jobs across all its chunks.
Q13. Why would an architect choose Queueable Apex over Batch Apex for a medium-sized job?
Batch Apex carries more overhead—it has its own start/execute/finish lifecycle and is built for very large record volumes. If you’re processing a moderate number of records (a few hundred to a few
thousand), and you need to pass a complex object or chain follow-up logic, Queueable Apex is lighter-weight, easier to monitor, and avoids taking up one of the org’s 5 concurrent batch job slots.
Batch Apex Interview Questions
Q14. What is Batch Apex and what problem does it solve?
Batch Apex lets us process large numbers of records—potentially millions—by splitting them into smaller chunks (batches), where each chunk runs as its own transaction with its own governor limits. We implement Database.Batchable with three methods: start() to define the scope, execute() to process each chunk, and finish() to run any wrap-up logic once all chunks complete.
Q15. What are the concrete advantages of Batch Apex?
- Every batch transaction starts fresh, with its own full set of governor limits.
- The platform automatically splits your record set into batches for you.
- If one batch fails, the other batches keep running independently, and any batch that already succeeded stays committed—a failure in batch 3 doesn’t undo batch 1 or batch 2.
Q16. Why use Batch Apex instead of writing the same logic in normal Apex?
Batch Apex is designed for large-volume processing because the work is divided into separate transactions:
- Large result sets: Database.QueryLocator can support up to 50 million records in a Batch Apex start() query.
- Fresh limits per batch execution—each execute() invocation gets its own transaction and governor-limit context.
- Configurable scope size: the batch scope can be configured up to 2,000 records.
- Failure isolation: a failure in one batch transaction doesn’t roll back previously committed batch transactions or prevent later batch transactions from being attempted.
Q17. What best practices should you follow when writing Batch Apex?
- Don’t use Batch Apex when a small number of records is involved—plain Apex (or Queueable) is simpler and faster.
- Be careful invoking a batch job from a trigger; make sure the trigger can’t accidentally launch more batch jobs than the org’s concurrent limit allows.
- A Batch Apex execution cannot invoke a Future method. If downstream asynchronous orchestration is needed, consider Queueable Apex instead.
- Use the required Batchable method visibility for your deployment context; don’t add
globalunless the class needs that visibility. - Keep any web service callouts inside
execute()as fast as possible. - Tune the SOQL query used in it
start()so it’s selective and indexed. - Minimize the total number of asynchronous requests your batch design fires off, to reduce the chance of delays elsewhere in the org.
Q18. Your batch job processes 2,000 records with a batch size of 200. During the second batch, record 298 fails on DML. What happens?
Because the batch size is 200, the first 200 records (batch one) were already committed successfully before the second batch even started—that commit is not affected by anything that happens later.
What happens in batch two depends entirely on how we perform the DML:
- If you use a plain DML statement like insert or update (without Database methods), one failing record causes the entire batch to roll back. So none of the records 201-400 get processed, even though only one record (298) actually failed.
- If you use Database.update(records, false) (setting allOrNone to false), the platform processes every record individually: 199 of the 200 records in that batch succeed and commit, and only record 298 fails and is skipped. The other batches (3, 4, and so on) are completely unaffected either way—batch failures never stop the remaining batches from running.
Q19. What’s the difference between Database.QueryLocator and Iterable in the start() method?
Database.QueryLocator runs a straightforward SOQL query to define a batch’s scope, and it bypasses the normal 50,000-record SOQL limit—it can return up to 50 million records, which is why it’s the default choice for most batch jobs.
Iterables<Object> let us build a custom scope—useful when our logic to determine “which records” can’t be expressed cleanly in a WHERE clause. The tradeoff is that an Iterable implementation still enforces the standard SOQL row limits since we’re building the record set ourselves rather than letting QueryLocator bypass them.
Q20. How many Batch Apex jobs can execute concurrently?
Salesforce allows up to 5 Batch Apex jobs to execute concurrently. Additional batch jobs can wait in the Apex Flex Queue, which can hold up to 100 batch jobs.
This is why we should avoid launching Batch Apex uncontrolled from triggers or other high-volume automation. A design that creates unnecessary batch jobs can consume the org’s batch capacity and increase processing delays.
Scheduled Apex Interview Questions
Q21. What is Scheduled Apex, and how do you schedule a class?
Scheduled Apex lets us run Apex on a recurring, cron-style schedule—daily, weekly, at a specific time, or on a custom cron expression. We implement the Schedulable interface and put our logic in the execute(SchedulableContext sc) method and register it using System.schedule().
public class NightlyCleanupJob implements Schedulable {
public void execute(SchedulableContext sc) {
Database.executeBatch(new CleanupOldRecordsBatch());
}
}
// Schedule it to run every day at 2 AM
String cronExpr = '0 0 2 * * ?';
System.schedule('Nightly Cleanup', cronExpr, new NightlyCleanupJob());
Q22. How many Scheduled Apex jobs can we have running concurrently?
An org can have up to 100 scheduled Apex jobs active at one time. This is a fixed platform limit, so if you’re designing a system with many recurring jobs, you need to plan around that ceiling—often by
consolidating logic into fewer scheduled classes that each kick off multiple batch or queueable jobs.
Q23. Can Scheduled Apex make callouts?
Not directly. Salesforce documents that synchronous web service callouts aren’t supported from Scheduled Apex. For an asynchronous callout, have the scheduled job delegate to Queueable Apex implementing Database.AllowsCallouts; for large-volume processing, it can delegate to Batch Apex that implements Database.AllowsCallouts.
Scenario-Based Async Apex Interview Questions
Q24. A user reports that after clicking “Save,” the page hangs for 15 seconds before returning. Your trigger needs to call a shipping API. How do you fix it?
Move the callout out of the trigger entirely. For new development, a common design is Trigger → handler/service → Queueable Apex. Queueable Apex implements the database. AllowsCallouts. The trigger enqueues the job and completes its own transaction; the Queueable performs the callout afterward.
Also consider whether the integration should be event-driven or middleware-based if multiple systems need the event or stronger decoupling is required.
Q25. You need to update 2 million Account records to recalculate a rollup field. Which async option do you pick, and why?
Batch Apex is best for this use case. Future methods and Queueable jobs aren’t designed for volumes anywhere close to 2 million records per transaction limit. Batch Apex’s Database.QueryLocator can retrieve up to 50 million records in start(), and processes them in manageable, independently-committed chunks (default 200 records perchunk), which is exactly the workload it was built for.
Q26. Your trigger needs to update both a custom object (non-setup) and a Group membership (setup object) in the same transaction. Users start seeing “Mixed DML” errors. How do you fix it?
Separate the setup-object DML and non-setup-object DML into different transactions. Asynchronous Apex can be one way to create that transaction boundary. For new development, prefer Queueable Apex where it fits the requirement rather than introducing a new Future method
solely for this purpose.
Also consider whether the business process can be redesigned so that the setup-object operation happens through a dedicated asynchronous or declarative process. The important interview concept is transaction separation, not “Future is the only solution.”
Q27. A batch job is meant to run nightly, but occasionally two instances end up running at the same time and duplicate the output file. What’s the likely cause and the fix?
The likely cause is duplicate job submission: a scheduled process, manual process, or automation submits another batch while an earlier instance is still active or queued.
For Batch Apex, you can query AsyncApexJob and apply an application-level guard before submitting another job. Also make the processing idempotent so that duplicate execution doesn’t create duplicate business results.
For Queueable Apex, Salesforce provides AsyncOptions and QueueableDuplicateSignature to help prevent duplicate queueable jobs from being enqueued. Do not rely on a job-status query alone for every concurrency problem.
Q28. Your team wants to chain three dependent steps: fetch data from an external API, transform it, then update 50,000 local records — each step depending on the previous one finishing. What design do you recommend?
Use chained Queueable Apex for the first two steps (the callout and the transform), since Queueable supports passing complex objects between steps and each step can enqueue the next from inside execute(). For the final step — updating 50,000 records — have the second queueable
job’s execute() kick off a Batch Apex job instead of trying to do the update inline, since 50,000 records is squarely batch-sized work rather than queueable-sized work.
Q29. A Future method is failing in production, but the user who initiated the transaction sees no error. Why, and how do you diagnose it?
The Future method runs in a separate transaction, so an exception in the Future execution doesn’t roll back the transaction that originally enqueued it.
Diagnose the problem using the asynchronous execution’s debug logs and, where applicable, AsyncApexJob information. For production-grade integrations and critical processing, add explicit application-level error logging and monitoring rather than relying on debug logs alone.
This is also a good interview opportunity to explain why Queueable is generally preferable for new asynchronous designs: it provides a job ID and better monitoring capabilities.
Q30. You need to perform a small asynchronous action after an Opportunity is closed-won. Should you use a Future method or Queueable Apex?
Both can perform asynchronous work, but for new development, Queueable Apex is generally the preferred choice. It provides a job ID, supports richer parameters, and can be extended with chaining or other Queueable capabilities later.
Future methods remain supported and may exist in legacy code, but Salesforce recommends Queueable Apex for new production implementations when it meets the requirement.
Q31. A batch job’s finish() method needs to send a summary email and then kick off a second batch job that depends on the first one’s results. How do you structure this?
Implement Database.Stateful on the first batch class so instance variables (like a running count or list of processed IDs) persist across all chunks and are available in finish().
Inside finish(), build the summary email using those preserved variables, send it with Messaging.sendEmail(), and then call Database.executeBatch() to launch the second batch job. This pattern , batch chaining via finish() is the standard way to run dependent, sequential batch jobs.
Q32. Your org has hit the daily async Apex execution limit and legitimate business jobs are getting blocked. What would you investigate first as an architect?
First, check whether any trigger or flow is uncontrollably enqueuing future methods, Queueable jobs, or batch jobs — for example, a trigger that calls System.enqueueJob() once per record in a bulk update, instead of once per transaction. Next, review whether recursive automation (a trigger re-triggering itself through DML) is multiplying async invocations. The fix is almost always architectural: batch the async calls at the transaction level, add recursion guards, and consolidate multiple small future/queueable calls into a single Queueable or Batch job wherever possible.
Q33. A Scheduled Apex job that used to run fine now throws a System.AsyncException: Maximum stack depth has been reached error. What’s happening?
This exception usually means a chain of queueable jobs (often launched from inside the scheduled job or a batch it triggers) has exceeded the platform’s queueable chaining depth limit. Some Salesforce editions or contexts restrict chain depth more tightly than others (for example, chains started from a batch or future context are capped at 5, versus 50 in a standard context).
The fix is to redesign the chain so it doesn’t recurse indefinitely—introduce a stopping condition or move the bulk of the repetitive work into Batch Apex instead of an ever-lengthening Queueable chain.
Q34. Can Apex Cursors replace Batch Apex?
Not universally. Apex Cursors can be combined with Queueable Apex to process large query result sets with a different programming model, but Batch Apex remains a strong choice when you need its built-in chunked transactions, start()/execute()/finish() lifecycle, and large-volume processing model.
Interview tip: Don’t answer “Apex Cursors replace Batch.” Explain the tradeoff and choose based on the workload and orchestration requirements.
Q35. When would you choose Platform Events instead of Queueable Apex?
Choose based on the problem you are solving. Queueable Apex is primarily for asynchronous work inside an Apex-driven process. Platform Events are useful when you need event-driven decoupling and multiple subscribers or downstream consumers should react independently to a business event.
Interview tip: If the requirement says “three independent systems should react when an order is created,” think event-driven architecture rather than three tightly coupled Queueable chains.
Flow vs Async Apex
Q. When should you use Flow instead of Async Apex?
Use Flow when the requirement fits well within declarative automation and doesn’t need the advanced control or scale characteristics of Apex.
Async Apex becomes a stronger option when you need complex Apex logic, large-volume processing, sophisticated orchestration, custom callout handling, or capabilities that aren’t practical in Flow.
Architect interview tip: Don’t choose Apex simply because it is more powerful. Start with the simplest platform capability that satisfies the requirement, then introduce asynchronous Apex when the transaction, volume, integration, or orchestration needs justify it.
Advanced Async Apex Questions
Transaction Finalizer
A Finalizer lets a Queueable job run guaranteed cleanup or follow-up logic after its execution finishes — whether it finished successfully or failed with an uncaught exception. You attach one with System.attachFinalizer() inside execute(), and implement the Finalizer interface’s execute(FinalizerContext context) method to check the outcome (context.getResult()) and react accordingly — for example, retrying a failed callout or logging the failure to a custom object.
public class MyFinalizer implements Finalizer {
public void execute(FinalizerContext ctx) {
if (ctx.getResult() == ParentJobResult.UNHANDLED_EXCEPTION) {
// log the failure or retry
}
}
}
AsyncOptions and Queueable Duplicate Signatures
AsyncOptions gives Queueable Apex additional control over asynchronous execution. It can be used to set a maximum queueable stack depth and a minimum queueable delay, and QueueableDuplicateSignature can help prevent duplicate Queueable jobs from being enqueued.
This is especially useful for trigger-driven processing where the same business event might otherwise enqueue duplicate jobs and create race conditions or record-locking problems.
Interview question: How would you prevent duplicate Queueable jobs?
Answer: For Queueable Apex, consider using AsyncOptions.DuplicateSignature with a deterministic QueueableDuplicateSignature. Also design the underlying business operation to be idempotent so duplicate delivery or retry does not produce duplicate business outcomes.
AsyncApexJob
AsyncApexJob is a standard object used to inspect asynchronous Apex job information. Commonly useful fields include Status, JobItemsProcessed, TotalJobItems, NumberOfErrors, and ExtendedStatus, depending on the job type and what the platform exposes.
Architects can use this information for operational monitoring, troubleshooting, and application-level safeguards such as detecting an already-running Batch Apex job.
Apex Cursors
Apex Cursors provide a way to iterate through large query result sets without requiring the full Batch Apex programming model. They can be combined with Queueable Apex for large-data processing patterns where you want more control over iteration and asynchronous orchestration.
They do not make Batch Apex obsolete. The right choice depends on the volume, transaction boundaries, orchestration needs, and whether Batch Apex’s built-in lifecycle is a better fit.
Chaining
Chaining refers to starting one async job from inside another — a Queueable job enqueuing a second Queueable job, or a batch job’s finish() method launching a second batch job. Chaining lets you break a multi-step process into sequential, dependent stages, each with its own fresh governor limits, instead of trying to force everything into a single execution window.
Callouts
Callouts (calls to external HTTP or SOAP services) are restricted in synchronous contexts like triggers, but supported in async contexts when explicitly enabled: @future(callout=true) for future methods, and implementing Database.AllowsCallouts for Queueable and Batch Apex classes. Scheduled Apex cannot make direct callouts, so it must delegate to a batch job that implements Database.AllowsCallouts (see Q23).
Scheduled Apex is primarily a scheduling mechanism. A schedulable class can be designed to perform callouts, and it can also delegate to Queueable or Batch Apex when the integration needs more robust asynchronous processing or large-volume handling.
Async Apex Testing Interview Questions
Q. How do you test a future method?
Wrap the calling code between Test.startTest() and Test.stopTest(). Any future method invoked in that block executes synchronously as soon as Test.stopTest() is called, so you can assert on its results immediately afterward.
Q. How do you test Batch Apex?
Call Database.executeBatch() insideTest.startTest() and Test.stopTest(). All batch chunks run synchronously the moment stopTest() executes, letting you query the affected records right after and assert the expected outcome.
Q. How do you test Queueable Apex, including chained jobs?
CallSystem.enqueueJob() inside Test.startTest()/Test.stopTest() and assert the resulting behavior after Test.stopTest(). For chained Queueable jobs, design tests around the behavior of each job and don’t ake assumptions that an arbitrarily long production chain will execute
exactly as it does in a test context.
Q. How do you test Scheduled Apex?
Use Test.startTest() and Test.stopTest() around a call to System.schedule() with a cron expression set slightly in the future. When stopTest() runs, the scheduled job executes, and you can then assert against the job’s effects.
Q. Can you unit test the exact execution time of an async job?
No,we can’t assert when Salesforce will run an async job in production, since the platform controls timing based on server load. In tests, Test.stopTest() forces synchronous execution specifically so you can test outcomes without depending on real-world timing.
10 Tricky Async Apex Interview Questions
Q. If a future method call fails after the enqueueing transaction has already committed, does the original record change get rolled back?
No. The original transaction was already committed before the future method ran, so a later failure inside the future method has no effect on data already saved by the calling transaction.
Q. Can you call System.enqueueJob() from inside a future method?
No, we cannot start a Queueable job from within a future method’s execution context.
Q. What happens if you call Database.executeBatch() with a batch size larger than 2,000?
The platform silently caps the batch size at 2,000 records per chunk; you can’t force chunks larger than that maximum.
Q. Does Test.stopTest() the guarantee every level of a Queueable chain executes in a test?
Not necessarily beyond the first chained job in some contexts—always verify test coverage for each link explicitly instead of assuming the whole chain unwinds.
Q. Can a Batch Apex job’s start() method itself perform a callout?
No — start() runs in the batch’s initial context and does not support callouts, even if the class implements Database.AllowsCallouts; only execute() can perform callouts.
Q. If a Queueable job is Database.Stateful, do instance variables persist across chained jobs, or just across chunks of the same job?
Database.Stateful preserves instance state within a single job’s lifecycle (useful for Batch Apex chunks); a newly chained Queueable job is a fresh instance, so it does not automatically inherit state from the job that enqueued it unless you explicitly pass that state through its constructor.
Q. Can two batch jobs of the same Apex class run at the exact same time in the same org?
Yes, as long as the org hasn’t exceeded its concurrent batch job limit — Salesforce doesn’t block duplicate class instances by default; you must guard against that yourself (see Q27).
Q. Does a Scheduled Apex job count against the 100 scheduled jobs limit while it’s actively executing, or only while it’s registered?
It counts while it’s registered via System.schedule(), regardless of whether it’s currently executing — the 100-job ceiling applies to how many scheduled jobs exist in the org’s schedule at once.
Q. Can a Visualforce or Lightning page directly display live progress from a running Batch Apex job?
Yes, indirectly — by having the page’s controller poll the AsyncApexJob object for fields like JobItemsProcessed and TotalJobItems and refresh the display, since there’s no native push mechanism from the batch job itself.
Q. If you enqueue a Queueable job from an already-running Queueable job that was itself started from a Batch Apex execute() method, what chaining depth limit applies?
The tighter limit applies — jobs chained from a batch or future context are limited to a maximum depth of 5, not the standard 50 allowed in ordinary contexts.
Async Apex Cheat Sheet
| Concept | Key Fact |
|---|---|
| Future method parameters | Primitives and collections of primitives only — no sObjects, no custom objects |
| Future method chaining | Not allowed—a future method cannot call another future method |
| Queueable parameters | Supports sObjects and custom Apex classes |
| Queueable chaining | Enqueue up to 50 jobs per transaction (5 if chained from batch/future context) |
| Queueable + Batch | Only one System.enqueueJob() allowed per execute() in a Batchable class |
| Batch default chunk size | 200 records (configurable up to 2,000 max) |
| Batch SOQL row limit | Up to 50 million with Database.QueryLocator; standard limits apply with Iterable |
| Batch heap size | ~12 MB per batch transaction (vs ~6 MB synchronous) |
| Batch failure isolation | A failure in one chunk does not roll back already-committed chunks |
| Scheduled Apex limit | Up to 100 concurrently scheduled jobs |
| Scheduled Apex callouts | Not supported directly—delegate to a Batch Apex class |
| Mixed DML fix | Isolate setup-object or non-setup-object DML inside a future method |
| Testing async code | Wrap the call in Test.startTest() / Test.stopTest() for synchronous execution |
| Monitoring | Query AsyncApexJob for Status, JobItemsProcessed, TotalJobItems, NumberOfErrors |
| Trigger callouts | Never direct—always delegate to future (callout=true) or Queueable (AllowsCallouts) |
Frequently Asked Questions
Current-platform note: Salesforce has introduced elastic limits for some asynchronous execution in beta in the Summer ’26 release. Because exact limits and feature availability can vary by release and org, use Salesforce’s current governor-limits documentation for numeric limits rather than treating this article as the final source of truth.
Q. Is Queueable Apex replacing future methods entirely?
Salesforce hasn’t deprecated future methods, but Queueable Apex is the recommended
default for new development because it supports richer parameters, chaining, and job monitoring that future methods lack.
Q. Can I run more than 5 Batch Apex jobs concurrently if I really need to?
Only five Batch Apex jobs can execute concurrently. Additional batch jobs can wait in the Apex Flex Queue, which supports up to 100 batch jobs. If your design routinely creates more batches than the platform can execute efficiently, reconsider the batching strategy rather than trying to bypass
the concurrency limit.
Q. Do async Apex jobs count against my org’s daily asynchronous execution capacity?
Yes. Future, Queueable, Batch, and Scheduled Apex consume asynchronous execution capacity. Salesforce can change how these limits are calculated or applied across releases, so avoid hard-coding a numeric daily limit in an evergreen article; link to the current Salesforce governor-limits documentation when discussing exact values.
Q. Which async type should I default to if I’m not sure?
Start with Queueable Apex for anything beyond a trivial one-off task, it covers most future-method use cases plus more, and reserve Batch Apex specifically for large-volume record processing and Scheduled Apex specifically for recurring, time-based execution.
Q. Can different async mechanisms be combined (for example, Scheduled Batch → Queueable)?
Yes. Combining mechanisms can be a valid enterprise pattern when each mechanism has a clear responsibility; for example, Scheduled Apex starts a recurring process, Batch Apex handles large-volume data processing, and Queueable Apex handles a downstream integration or follow-up step.
The design should still respect enqueue limits, transaction boundaries, error handling, and idempotency.
Summary
Asynchronous Apex interview questions rarely test whether you’ve memorized syntax—they test whether you understand why Salesforce built four distinct mechanisms and when to reach for each one. If you can confidently explain the tradeoffs in the comparison table above, walk through the scenario questions with real reasoning, and recite the cheat sheet without hesitating, you’re ready for anything from a junior developer screen to a senior architect panel.
If this guide helped you prep, bookmark it, and check out the related Apex and architecture interview guides on SalesforceCodex for the next round of your interview prep.
Similar Posts for Salesforce Interview Question
- Salesforce Interview Question for Integration
- Salesforce Apex Interview Question
- Queueable Vs. Batch Apex In Salesforce
- Avoid Batch Apex and Use Queueable Class
- Difference Between With Security and Without Security in Apex
- Mastering Technical Questions for Tech Lead/Salesforce Architect Interview-4
- 20 Technical Questions to Test Your Skills in a Tech Lead/Salesforce Architect Interview-3
- Interview Questions for Tech Lead /Salesforce Architect Interview – II
- Top 20 Technical Questions for Tech Lead /Salesforce Architect Interview – I
- Top 30 Scenario-Based Salesforce Developer Interview Questions
- 20 Scenario-based Salesforce Developer Interview Questions
- How to Choose Between SOQL and SOSL Queries
- Can the future method be executed from batch Apex?
- 20 Scenario-based Salesforce Developer Interview Questions
- What is SOQL Injection?
- What is PK Chunking?
References:

Dhanik Lal Sahni is a Salesforce Solution Architect, Independent Consultant, and the founder of SalesforceCodex.com. With nearly two decades of IT experience and extensive expertise in Salesforce architecture, he helps startups and enterprises design scalable, secure, and high-performance CRM solutions using Sales Cloud, Service Cloud, Experience Cloud, Data Cloud, Apex, Lightning Web Components (LWC), and enterprise integration patterns.
Through SalesforceCodex, he shares practical tutorials, real-world implementation guides, enterprise architecture best practices, and interview preparation resources for Salesforce Developers, Architects, and Administrators.
Learn more about his Salesforce consulting and freelance services at dhaniksahni.com.

8 Comments
Pingback: What is SOQL Injection? - SalesforceCodex
Pingback: Class 5 EVS Quiz 1 for Chapter Super Senses - ProveGuru.com
The interview questions & explanation is easy to understand . Thank you!!
Welcome, Sheetal. I am happy, it is easy to understand.
Thank You,
Dhanik
Pingback: Top 30 Scenario-Based Salesforce Developer Interview Questions - Salesforce Codex
Pingback: Salesforce Architect Interview Questions - Salesforce Codex
Pingback: Questions for Tech Lead/Salesforce Architect Interview
Pingback: Top 20 Salesforce Data Cloud Interview Questions & Answers