The Evolution of Large-Scale Data Handling in Apex
For years, Salesforce developers have relied on Batch Apex or SOQL offsets to handle large datasets. However, these methods often come with significant overhead, state management complexity, or strict limits (like the 2,000-record offset limit). With the Spring ’26 release, Apex Cursors have moved to General Availability (GA), introducing a high-performance, stateless way to navigate up to 50 million records efficiently.
What are Apex Cursors?
Apex Cursors provide a server-side pointer to a query result set. Unlike traditional SOQL, which retrieves all results at once or requires manual batching, a cursor allows you to fetch chunks of data on demand. This is particularly transformative for long-running processes where you need to maintain a position across different execution contexts or transactions.
Key Technical Capabilities
- Massive Scale: Cursors can handle result sets up to 50 million records, vastly exceeding standard SOQL limits.
- Stateless Resumability: You can store a
CursorIdand a position, allowing a different transaction (such as a later Queueable or a separate API call) to resume processing from the exact same point. - Consistent UI Pagination: The new
PaginationCursorclass ensures that if records are deleted while a user is paging through a list, the page size and offsets remain consistent.
Code Implementation: Fetching Data in Batches
Implementing a cursor is straightforward. Here is a pattern for processing a large volume of contacts using the new Database.Cursor class:
// Create a cursor for high-volume processing
Database.Cursor cursor = Database.getCursor(
'SELECT Id, Name, Email FROM Contact WHERE CreatedDate = THIS_YEAR'
);
// Process records in batches of 200
while (cursor.hasNext()) {
List<Contact> batch = cursor.fetch(200);
for (Contact c : batch) {
System.debug('Processing: ' + c.Name);
}
}
// Save position for potential resumption in another transaction
String cursorId = cursor.getCursorId();
Integer lastPosition = cursor.getPosition();Apex Cursors vs. Batch Apex
While Batch Apex remains useful for standard asynchronous processing, Cursors offer distinct advantages for Architects:
| Feature | Batch Apex | Apex Cursors |
|---|---|---|
| Record Limit | 50 Million | 50 Million |
| Flexibility | Rigid structure (Start, Execute, Finish) | Highly flexible; can be used in Queueables, REST, etc. |
| Consistency | Snapshot-based | Cached results; PaginationCursor handles deletions |
| Overhead | High (Job queuing/tracking) | Low (On-demand fetching) |
Architectural Governance and Limits
To ensure platform stability, Salesforce has implemented specific limits for Cursors in the Spring ’26 release:
- Instance Limit: 10,000 cursor instances per 24-hour period per org.
- Result Set Size: 50 million records for standard cursors; 100,000 for PaginationCursors.
- Timeout: Cursors are cached for a limited window; long-term storage of cursor IDs should be avoided.
By adopting Apex Cursors, technical architects can now design more responsive, scalable, and memory-efficient data integration and processing layers that were previously impossible without complex external middleware.








Leave a Reply