Batch Apex is a cornerstone of Salesforce development, enabling developers to process large volumes of data asynchronously while adhering to Salesforce’s strict governor limits. Whether you’re updating millions of records, integrating with external systems, or performing complex data transformations, Batch Apex is the go-to solution. However, to truly harness its power, understanding the differences between QueryLocator and Iterable is essential.
While QueryLocator is perfect for simple SOQL queries on a single object, Iterators provide unmatched flexibility when dealing with multiple objects, external data sources, or complex processing logic. This blog will explore how to master Batch Apex with Iterators, including key use cases, governor limits, and best practices.
What I’ll Cover in This Blog
🔹 What is Batch Apex, and why do we use it?
🔹 QueryLocator vs. Iterator: When to use each
🔹 How to implement Batch Apex with Iterators for multiple objects
🔹 Step-by-step explanation of the code
🔹 How to monitor and debug Batch Apex jobs
🔹 Batch Apex Limitations and Best Pratices
By the end of this guide, you’ll be able to implement custom Iterators in Batch Apex to process multiple objects efficiently.
What is Batch Apex?
Batch Apex is a Salesforce feature that allows you to process large datasets in smaller, manageable chunks (batches). It runs asynchronously, meaning it operates in the background, freeing up resources for other tasks. Batch Apex is ideal for:
- Processing millions of records.
- Performing complex calculations or transformations.
- Integrating with external systems via callouts.
- Ensuring compliance with Salesforce governor limits.
Key Components of Batch Apex
To use Batch Apex, you need to implement the Database.Batchable interface, which consists of three methods:
start Method:
- Defines the scope of the batch job.
- Returns either a Database.QueryLocator or an Iterable<sObject>.
- Use QueryLocator for simple SOQL queries or Iterable for complex data processing.
execute Method:
- Processes each batch of records.
- Contains the core logic for data manipulation.
- Runs in a separate transaction for each batch.
finish Method:
- Executes post-processing logic after all batches are processed.
- Ideal for sending notifications, logging results, or chaining additional jobs.
QueryLocator vs. Iterable: When to Use Which?
QueryLocator
- Use Case: Simple SOQL queries on a single object.
Advantages:
- Can query up to 50 million records.
- Bypasses the SOQL row limit for single-object queries.
- Optimized for large datasets.
Limitations:
- Limited to single-object queries.
- Cannot handle complex data transformations or multi-object scenarios.
Iterable
- Use Case: Complex scenarios involving multiple objects, external data, or custom logic.
Advantages:
- Highly flexible; can process data from multiple sources.
- Allows custom filtering, transformations, and logic.
- Can handle data from external APIs or mixed record types.
Limitations:
- Subject to SOQL governor limits (50,000 records per transaction).
- Slightly slower due to custom logic and potential external API calls.
When Should You Use Iterators in Batch Apex?
✔️ Multiple Objects: Process records from multiple objects (e.g., Accounts, Contacts, and Custom Objects) in a single batch job.
✔️ External Data: Fetch and process data from external APIs or systems.
✔️ Custom Logic: Apply dynamic filtering, transformations, or calculations before processing records.
✔️ Mixed Record Types: Handle diverse record types that require specialized processing logic.
Implementing Batch Apex with Iterators for Multiple Objects
Now, let’s walk through an example of processing multiple objects (Accounts, Contacts, and an Opportunity Object).
Step 1: Create a Wrapper Class
We need a wrapper class to store records from different objects.

🔹 This class holds both the object type (e.g., Account, Contact) and the record data.
Step 2: Create a Custom Iterator
Our Iterator will fetch records from multiple objects and return them one by one.


🔹 This gathers data from multiple objects and stores them in a list.
Step 3: Create an Iterable Class
The Iterable class returns an instance of our custom Iterator.

🔹 This allows Batch Apex to fetch records from multiple sources.
Step 4: Create the Batch Apex Class
Now, let’s build our Batch Apex job to process these records.


🔹 This batch job updates multiple objects dynamically based on their type.
How to Run the Batch Job?
To start the batch job, run this command in Developer Console:

This will process 5 records per batch.
How to Monitor and Debug Batch Jobs?
View Batch Job Status in Salesforce UI:
1️⃣ Go to Setup → Apex Jobs
2️⃣ Search for your batch job name
3️⃣ Check status (Queued, Processing, Completed, Failed)

View Logs in Developer Console:

Governor Limits and Best Practices
Governor Limits
- Concurrent Jobs: Up to 5 batch jobs can be queued or active concurrently.
- Apex Flex Queue: Up to 100 batch jobs can be held in the Apex flex queue.
- Daily Async Executions: Maximum of 250,000 asynchronous Apex executions per 24 hours (or user licenses × 200, whichever is greater).
- QueryLocator Limit: Can query up to 50 million records.
- Callouts: Up to 100 callouts per transaction (for each start, execute, or finish method).
- Batch Size: Default batch size is 200 records, but you can specify a custom size (up to 2,000 for QueryLocator).
Best Practices
- Minimize Batch Size: Use the smallest possible batch size to avoid hitting governor limits (e.g., CPU time, heap size).
- Use Database.Stateful: Maintain state across transactions for counting or summarizing records.
- Avoid Future Methods: Future methods are not allowed in batch Apex classes.
- Optimize Queries: Avoid relationship subqueries in QueryLocator to leverage faster chunking implementation.
- Handle Callouts Carefully: Use Database.AllowsCallouts and ensure callouts are idempotent to avoid duplicate processing.
- Test Efficiently: Use Test.startTest() and Test.stopTest() to ensure asynchronous batch jobs complete during tests.
- Monitor Jobs: Use the AsyncApexJob object to track job progress and handle failures.
- Chain Batch Jobs: For complex workflows, chain batch jobs by calling Database.executeBatch from the finish method (API version 26.0+).
- Prioritize Jobs: Use the Apex Flex Queue to reorder and prioritize batch jobs.
- Avoid Trigger Invocations: Be cautious when invoking batch jobs from triggers to avoid exceeding concurrent job limits.
Conclusion: Mastering Batch Apex with Iterators for Handling Multiple Objects
Mastering Batch Apex with Iterators unlocks powerful capabilities in Salesforce development. It ensures that your batch processes are not just efficient but also flexible, scalable, and maintainable. By implementing iterators, you gain full control over the records being processed, making your batch jobs smarter and more adaptable to real-world business needs.
Start using Iterators in your Batch Apex today, and take your Salesforce automation skills to the next level!