When we write any SOQL query, we may sometimes face the System.LimitException: Too many query rows error message. This occurs when more than 100 SOQL queries are executed in a synchronous context (or 200 in an asynchronous context).
To avoid this error, which occurs due to the governor limit, we have established some best practices to prevent it.
In this tutorial, we will learn about the SOQL Governor limits in Salesforce and what these limits are. After that, I will explain how to write a SOQL query to avoid exceeding the governor limit in Salesforce.
What is the Governor Limit in Salesforce?
Governor limits in Salesforce are restricted in runtime by the platform to ensure efficient resource usage and prevent a single process from controlling system resources in a multi-tenant environment. These limits apply to Apex, SOQL, DML operations, and other system resources.
What are SOQL Governor Limits in Salesforce?
SOQL (Salesforce Object Query Language) is used to retrieve records from Salesforce objects. However, due to Salesforce’s shared infrastructure, the number of SOQL queries and the amount of data they retrieve are restricted to ensure optimal performance.
First, let us understand how many records we can retrieve without exceeding the SOQL governor limit in Salesforce.
Total Number of SOQL Queries:
- Synchronous context (Single transaction): 100 queries
- Asynchronous context (Batch, Future, Queueable, or Scheduled Apex): 200 queries
Number of Records Retrieved:
- A single SOQL query can return a maximum of 50,000 records.
- If more than 50,000 records are required, batch processing techniques like batch apex are used.
Reasons and Solution for Exceeding SOQL Governor Limits
The following are some reasons for exceeding governor limits because of the bad practices of writing SOQL queries in Salesforce.
If an execution context (Apex code, trigger, or batch job) exceeds these SOQL limits, Salesforce throws a System.LimitException, which cannot be caught or handled using try-catch blocks. This results in the immediate termination of the execution.
Reason: SOQL Query Inside a Loop
Let us understand how the governor limit gets exceeded when we write the SOQL query inside the loop, and which error occurs in Salesforce.
For example, we want to retrieve 150 records from the contact object related to the account. For that, when we write the SOQL query inside the loop to retrieve records from the contacts, let’s see what will happen.
In the Apex class below, we created a method. Then, in the for loop, we create a Sobject instance, which is an account object, and pass the retrieved 150 account records.
Now, we want to display contacts related to accounts. For that, we created a List Collection and a written query to get the contact details.
After that, using a debug statement, we displayed the retrieved contacts. Save the Apex code and execute it using an anonymous window.
public class SOQLlimits {
public void GetRecords(){
for ( Account acc : [ SELECT Id FROM Account LIMIT 150 ] ) {
List<Contact> contacts = [ SELECT Id FROM Contact WHERE AccountId = :acc.Id ];
System.debug( contacts );
}
}
}As you click the execute button, you will see the following error: System.LimitException: Too many SOQL queries: 101. which means this error occurs because of the governor limit we have for the total number of SOQL queries, which is 100.
We have used the SOQL query inside the loop 150 times, and we got this error. Below, I have provided a solution to avoid this type of governor limit error or prevent exceeding the SOQL governor limit in Salesforce.

Solution: Use a Bulkified SOQL Query
Let’s understand the best practice for writing SOQL queries in Salesforce to avoid exceptions and exceed the SOQL governor limit.
For the same example, we first fetched all accounts and stored them in a list collection. After that, we created a set collection to store the account IDs, as it was designed to store unique values.
After that, in the for loop, we passed the account list to the account instance, and then, using the list add() method, we added account IDs to the set collection.
And now, outside of the for loop, we have written the query to retrieve the contacts related to the account of the binding variable of accountID. Again, using a for loop, we displayed the retrieved records.
Why didn’t we exceed the governor’s limit here? Because we have written the SOQL query outside the for loop, it executed only once.
public class SOQLlimits {
public void GetRecords(){
List<Account> accList = [ SELECT Id FROM Account LIMIT 150 ];
Set<Id> accIds = new Set<Id>();
for ( Account acc : accList ) {
accIds.add( acc.Id );
}
List<Contact> contacts = [ SELECT Id, Name, Account.Name FROM Contact WHERE
AccountId IN :accIds ];
for (Contact con : contacts) {
system.debug( 'Account Name : ' + con.Account.Name + ' ' +'Contact Name : ' +
con.Name);
}
}
}Here, you can see the query result, the account name, and the associated contact have been displayed.

Reason: Retrieving More Than 50,000 Records in a Single Query
For example, we want to retrieve all records from the contact object. If we have more than 50,000 records in the object, then we will get the System.LimitException: Too many query rows: 50001 error.
If you write the below SOQL query to retrieve more than 50,000 records, then the above error will occur. This error occurs because the governor limit of 50,000 for retrieving records from any object has been exceeded.
List<Contact> contacts = [ SELECT Id, Name FROM Contact ];
System.debug( contacts.size());Solution: Batch Apex to process large datasets.
Let’s understand how to avoid the System.LimitException: Too many query rows: 50001 error that occurs the exceeding SOQL governor limit. Since the query returns more than 50,000 records, we need to use Batch Apex to process the records in separate blocks.
Below, I have created a batch Apex class that implements the Database.Batchable <sObject> interface. In this, we have three methods: start(), execute(), and finish().
In the start() method, Database.getQueryLocator enables efficient handling of millions of records without exceeding SOQL limits. It retrieves records as we pass a SOQL query that will be processed in blocks or batches.
Then, we have the execute() method, which is called multiple times, once for each batch of records. The for loop iterates over each contact and prints their name. The batch size (default: 200) determines the number of records processed in each execution.
Then, the finish() method is optional. This method runs after all batches have been processed. We can use the method for post-processing tasks, such as displaying a success message, sending email notifications, logging batch completion, and triggering another batch job.
public class SOQLlimits implements Database.Batchable <sObject> {
public Database.QueryLocator start ( Database.BatchableContext BC ) {
return Database.getQueryLocator ( 'SELECT Id, Name FROM Contact' );
}
public void execute ( Database.BatchableContext BC, List<Contact> contactList ) {
System.debug( 'Processing batch size: ' + contactList.size());
for ( Contact con : contactList ) {
System.debug ( 'Contact Name: ' + con.Name );
}
}
public void finish ( Database.BatchableContext BC ) {
System.debug ( 'Batch processing completed.' );
}
}After that, we need to execute the batch Apex code. To do this, open the anonymous window and enter the code below.
SOQLlimits batch = new SOQLlimits();
Database.executeBatch ( batch, 200 );After executing the Apex code, you can see the finally() method gets executed, which means the SOQL query we have written has been executed successfully without exceeding the governor limit or error.

Conclusion
I hope you have got an idea about the SOQL governor limits in Salesforce and what the governor limit is. After that, I explained the reasons for exceeding the SOQL governor limits and how to write a SOQL query to avoid exceeding the governor’s limit in Salesforce.
You may like to read:
- Selective SOQL Queries in Salesforce
- Salesforce SOQL Inner Join and Outer Join Relationships
- Salesforce SOQL Distinct Queries
- LIKE Clause in SOQL
- Salesforce Object Search Language (SOSL) in Apex
I am Bijay Kumar, the founder of SalesforceFAQs.com. Having over 10 years of experience working in salesforce technologies for clients across the world (Canada, Australia, United States, United Kingdom, New Zealand, etc.). I am a certified salesforce administrator and expert with experience in developing salesforce applications and projects. My goal is to make it easy for people to learn and use salesforce technologies by providing simple and easy-to-understand solutions. Check out the complete profile on About us.