Recipes by Category

App Distribution (2) Bundle logic, interface and services for distribution. App Logic (37) The Apex programming language, workflow and formulas for logic. Collaboration (5) The Salesforce Chatter collaboration platform. Database (29) Data persistence, reporting and analytics. Integration (33) Web Service APIs and toolkits for integration. Security (9) Platform, application and data security. Tools (4) tooling User Interface (36) Visualforce MVC and metadata-drive user interfaces. Web Sites (12) Public web sites and apps with optional user registration and login.
Beta Feedback
Cookbook Home » Implementing the query()/queryMore() Pattern

Implementing the query()/queryMore() Pattern

Post by Developer Force  (2010-07-16)

Status: Certified
Level: novice


You need to issue queries that return more than 2,000 records, but the query() call can only return up to 2,000 at a time.


Use queryMore() to retrieve any additional records in batches of up to 2,000 at a time. The queryMore() call takes a single queryLocator parameter that specifies the index of the last result record that was returned. This queryLocator is created and returned by the previous query() or queryMore() call.

When the query() or queryMore() calls return a result with the isDone flag set to true, there are no more records to process.

For example, the following Java code implements the query()*/queryMore()* pattern when querying leads:

QueryResult queryResult = this.stub.query("Select name From lead");
do {
    for(sObject lead : queryResult.getRecords()) {
    queryResult = this.stub.queryMore(queryResult.
} while(true);

This code implements query()*/queryMore()* in VB.NET:

Dim lead As sforce.sObject
Dim i As Integer
Dim qr As sforce.QueryResult = binding.query("select name from lead")
     For i = 0 To qr.records.Length
        lead = qr.records(i)
        If qr.done Then Exit Do
        qr = binding.queryMore(qr.queryLocator)

The query()*/queryMore()* batch size defaults to 500 records, but can be as small as 200 or as large as 2000. To change the batch size, use the QueryOptions header.

  • If you use query()*/queryMore()* during a long-running integration scenario where you need to log in again to get new session IDs, the queryLocator cursor remains valid after you log in, as long as you get the next batch of records within fifteen minutes of idle time.
  • Only 10 queryLocator cursors can be active for an organization at any one time.


Recipe Activity - Please Log in to write a comment

Be the first to comment.


Vote to Verify a Recipe

Verifying a recipe is a way to give feedback to others and broaden your own understanding of the capabilities on When you verify a recipe, please make sure the code runs, and the functionality solves the articulated problem as expected.

Please make sure:
  • All the necessary pieces are mentioned
  • You have tested the recipe in practice
  • Have sent any suggestions for improvements to the author

Please Log in to verify a recipe

You have voted to verify this recipe.