
In the summer’24 release, Salesforce introduced Apex cursors (Beta). This feature allows developers to process large SOQL query results into small, manageable pieces within the limits of a single transaction. This approach is particularly useful when dealing with extensive result sets that might exceed the platform’s memory or processing limits. Cursors provide the flexibility to traverse the result set incrementally, enabling forward and backward navigation. Cursors offer an alternative to batch Apex, addressing certain limitations and providing enhanced capabilities, such as the ability to be used in a chain of queueable Apex jobs.
Apex Cursors are a game-changer for handling high-volume and resource-intensive processing jobs. Unlike batch Apex, which can be limiting in certain scenarios, Cursors offer more flexibility and power, allowing you to work with large SOQL query result sets efficiently.
So, what exactly are Apex Cursors, and how do they work? Cursors are stateless and generate results from a specified offset position using the Cursor.fetch(integer position, integer count) method. This means you can break down the processing of a large query result set into smaller, manageable chunks, traversing the result set in parts while navigating forward and backward as needed.
One of the key advantages of Apex Cursors is their ability to be used in a chain of queueable Apex jobs, providing a seamless way to handle large-scale processing tasks asynchronously. This feature is particularly useful for package developers and advanced Salesforce developers working with high-volume data processing scenarios.
But wait, there’s more! Apex Cursors come with their own set of governor limits, ensuring that your processes stay within the bounds of Salesforce’s platform. Here are some key limits to keep in mind:
- Maximum number of rows per cursor: 50 million (both synchronous and asynchronous)
- Maximum number of fetch calls per transaction: 10 (both synchronous and asynchronous)
- Maximum number of cursors per day: 10,000 (both synchronous and asynchronous)
- Maximum number of rows per day (aggregate limit): 100 million
To help you manage these limits, Salesforce has introduced new methods in the Limits class, such as Limits.getApexCursorRows() and Limits.getFetchCallsOnApexCursor(), along with their respective upper bound methods.
Apex Cursors also come with their own set of exceptions, including System.FatalCursorException and System.TransientCursorException. Transactions that fail with System.TransientCursorException can be retried, providing additional flexibility in handling errors.
Scenario: Suppose you have a requirement to update a field on all contact records that haven’t been modified in the last 400 days. Given that there could be more than 50,000 such records, you can use an Apex cursor to fetch and process the records in chunks.
Here’s how you can do it:
public class ContactUpdateQueueable implements Queueable {
private Database.Cursor locator;
private Integer position;
public ContactUpdateQueueable() {
locator = Database.getCursor('SELECT Id FROM Contact WHERE LastModifiedDate <= LAST_N_DAYS:400');
position = 0;
}
public void execute(QueueableContext ctx) {
List<Contact> scope = locator.fetch(position, 200);
position += scope.size();
// Update the contacts
for (Contact c : scope) {
c.SomeField__c = 'Some Value';
}
update scope;
// If there are more records, enqueue another job
if (position < locator.getNumRecords()) {
System.enqueueJob(this);
}
}
}
In this example, the ContactUpdateQueueable class fetches and updates Contacts in chunks of 200. After updating each chunk, it checks if there are more records to process. If there are, it enqueues another job to process the next chunk. This process continues until all records have been processed.
You would start the process by enqueuing the first job:
System.enqueueJob(new ContactUpdateQueueable());
Overall, Apex Cursors represent a powerful addition to the Salesforce developer toolkit, opening up new possibilities for efficient and scalable data processing. Whether you’re working with large contact lists, massive data migrations, or complex data transformations, Apex Cursors has got your back.
So, what are you waiting for? Dive into the world of Apex Cursors and unleash the power of large data processing in Salesforce. Happy coding!
About the blog
SFDCLessons is a blog where you can find various Salesforce tutorials and tips that we have written to help beginners and experienced developers alike. we also share my experience and knowledge on Salesforce best practices, troubleshooting, and optimization. Don’t forget to follow us on:
Newsletter
Subscribe to our email newsletter to be notified when a new post is published.
