Batch Apex
Batch Apex is designed for processing large volumes of data by dividing the workload into smaller, manageable batches. It’s implemented by defining a class that implements the Database.Batchable interface, with the required start, execute, and finish methods
Advantages:
Governor Limits Reset per Batch-Each batch runs in its own transaction, which means governor limits reset for every execution-great for handling large data sets safely
Batch Fault Isolation- If one batch fails, it doesn’t roll back successful processing in other batches
Large-scale Processing- You can process up to 2,000 records per batch, and even handle up to 50 million records through Database.QueryLocator-beyond that, the job fails
Limitations:
Concurrency Limit- Only up to 5 batch jobs can be queued or active at once
No @future Calls Allowed- You cannot call methods marked with @future
from Batch Apex
Queueable Apex
Queueable Apex offers a lighter asynchronous processing model than Batch Apex, but with more capabilities than traditional @future methods. You implement it via the Queueable interface and enqueue jobs with System.enqueueJob(…), which returns a Job ID you can monitor.
Advantages:
Supports Non-Primitive Member Variables- You can pass in complex objects like sObjects or custom types—something @future doesn’t allow
Job Monitoring via Job ID- The returned AsyncApexJob ID allows tracking and monitoring through the Apex Jobs UI or via SOQL
Job Chaining- You can enqueue a new Queueable job from within an executing one— useful for sequential, dependent tasks
Limitations:
Chaining Constraints- You may only chain one child job per parent, and can enqueue up to 50 jobs in a single transaction
When to Use Which?
Use Batch Apex when you need to process large datasets efficiently (tens to millions), especially when processing logic can be broken into clear batches and governor limits need resetting per chunk.
Use Queueable Apex for more flexible, lightweight, and sequential asynchronous tasks, especially when you want chaining, need to pass complex objects, or need simpler code setup.