You are here because you’ve encountered the System.LimitException: Too many SOQL queries: 101 error in Apex, it means your code is exceeding Salesforce’s governor limit of 100 SOQL queries per synchronous transaction (or 200 in asynchronous execution).
In this article I will explain you the causes of this error and provide best practices to fix it.
Why Does This Error Occur?
The error occurs when too many SOQL queries run within a single execution context. Common reasons include:
❌ SOQL inside a loop – Querying records repeatedly in a loop
❌ Recursive triggers – Trigger updates causing additional queries
❌ Inefficient data retrieval – Running multiple queries instead of a bulk fetch
Let’s look at the mistakes that cause this error and how to fix them.
Common Mistakes & Fixes
Running SOQL Inside a Loop
Each iteration executes a separate query, quickly reaching the governor limit.
Bad Practice:
for (Account acc : accountList) { Contact[] contacts = [SELECT Id, Name FROM Contact WHERE AccountId = :acc.Id]; // ❌ SOQL inside loop }
✅ Fix: Bulk Query Using a Map
Set<Id> accountIds = new Set<Id>(); for (Account acc : accountList) { accountIds.add(acc.Id); } Map<Id, List<Contact>> contactMap = new Map<Id, List<Contact>>(); for (Contact c : [SELECT Id, Name, AccountId FROM Contact WHERE AccountId IN :accountIds]) { if (!contactMap.containsKey(c.AccountId)) { contactMap.put(c.AccountId, new List<Contact>()); } contactMap.get(c.AccountId).add(c); }
This approach retrieves all related contacts in one query, avoiding repeated SOQL calls.
Recursive Trigger Execution
If a trigger modifies records, causing the trigger to fire again, it leads to multiple SOQL queries.
✅ Fix: Use Static Variables to Prevent Recursion
public class AccountTriggerHelper { private static Boolean isExecuted = false; public static void processAccounts(List<Account> accList) { if (!isExecuted) { isExecuted = true; // Perform operations } } }
This ensures the logic runs only once per transaction.
Fetching Related Records Separately
Querying child records separately instead of using a relationship query leads to unnecessary SOQL calls.
Bad Practice:
for (Account acc : [SELECT Id FROM Account]) { List<Contact> contacts = [SELECT Id FROM Contact WHERE AccountId = :acc.Id]; // ❌ Multiple queries }
✅ Fix: Use Relationship Queries
List<Account> accounts = [SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account];
This retrieves parent and child records in a single query.
✅ Best Practices to Avoid SOQL 101 Errors
- Move SOQL queries outside loops.
- Use collections (List, Set, Map) for bulk processing.
- Leverage relationship queries.
- Use Asynchronous Apex.
- Bulkify triggers to handle multiple records efficiently
Also, check out the below video on What are governor limits in Salesforce.
We hope now you will be able to resolve System.LimitException: Too many SOQL queries: 101. If you have any doubts then let us know in the comment box below.