Query Cursors in Salesforce Apex: The End of Batch Apex for Large Data Processing?

Discover how Salesforce’s new Query Cursors (Beta) transform large data processing in Apex. Learn how they eliminate the need for Batch Apex, handle millions of records efficiently, and simplify async data operations.

Upendra Kumar

11/6/20252 min read

For years, Salesforce developers have relied on Batch Apex to process large datasets.
It worked - but not without pain.

Governor limits. Serialization complexity. State management.
If you have ever written multiple batch classes just to stay under limits, you know exactly what I mean.

Now, Salesforce has quietly dropped a game-changing feature in Apex (Beta) - Query Cursors.

And they might just redefine how we handle large-scale data processing.

What Are Query Cursors in Apex?

Query Cursors introduce a cursor-based SOQL execution model — meaning you can query massive datasets and process them incrementally without hitting query or heap size limits.

Instead of splitting records across multiple batches, you create a cursor handle that lets you fetch records chunk by chunk.
Think of it as a controlled, serializable way to scroll through your data.

How Query Cursors Work

The process is simple and elegant:

  1. Create a Cursor

QueryCursor cursor = Database.queryWithCursor(
'SELECT Id, Name FROM Account WHERE Industry = \'Finance\''
);

  1. Fetch a Chunk of Records
    List<Account> records = cursor.fetch(2000); // Fetch 2K records

  2. Continue Fetching by Position

    while(cursor.hasMore()) {
    List<Account> nextSet = cursor.fetchNext(2000);
    processRecords(nextSet);
    }

  3. Check Total Record Count

    Integer totalCount = cursor.getTotalRecordCount();
    System.debug('Total Records: ' + totalCount);

Each fetch call retrieves the next set of records without re-running the query or re-consuming governor limits.

Why Query Cursors Are So Powerful

Let’s break down what makes this feature such a big deal:

1. Fully Serializable as Apex Job State

Query cursors can persist state between asynchronous executions.
No more manually managing offsets or record markers in Batch Apex.

2. Directly Created from SOQL

No extra classes or Database.Batchable interfaces.
Just run a query, and Salesforce gives you a cursor to navigate it.

3. Fetch by Position

You control exactly where to start and stop fetching.
Perfect for partial data loads, async jobs, or scheduled processes.

4. Total Record Count

You get the full dataset count instantly, helping with progress tracking or UI pagination.

Here is the sample code:


















Practical Use Cases

  • Migrating or syncing large datasets

  • Data archival or cleanup jobs

  • Analytics or aggregation over large records

  • Incremental ETL inside Apex jobs

And since cursors are serializable, they open doors for robust async architectures that don’t depend on custom batch frameworks.

Limitations (as of Beta)

Like any new feature, there are caveats:

  • Currently in Beta - APIs and limits may change

  • Available only in specific Apex runtime contexts

  • Limits on concurrent cursors per org/session may apply

  • No DML in the same transaction as cursor fetch (recommended pattern: async chain)

But as Salesforce matures this feature, expect it to become a core alternative to Batch Apex.

Final Thoughts

Salesforce Query Cursors mark a major leap toward simpler, more efficient data handling in Apex.

Instead of worrying about limits and batch chunking, developers can now:

  • Query once

  • Stream data efficiently

  • Scale processing smoothly

Batch Apex is not dead yet but Query Cursors are a glimpse into the future of scalable Apex.

🔍 TL;DR

Query Cursors in Apex (Beta) let you:
→ Handle large data sets efficiently
→ Avoid governor and heap limits
→ Move away from Batch Apex
→ Build scalable async jobs with less code

If you have ever written a Batch class just to process 100K records, it’s time to give Query Cursors a try.