Understanding the Too Many SOQL Queries: 101 Error
The "Too Many SOQL Queries: 101" error occurs when your Salesforce code executes more than 100 SOQL queries in a single transaction. This is a governor limit imposed by Salesforce to ensure efficient resource usage in its multi-tenant environment.
Salesforce strictly enforces this limit to prevent any single process from monopolizing shared resources. When exceeded, it throws a runtime exception that cannot be handled.
Causes of the Too Many SOQL Queries: 101 Error
SOQL Queries Inside Loops
The most common cause is placing SOQL queries inside loops. For example:
apexfor (Account acc : [SELECT Id FROM Account]) { List<Contact> contacts = [SELECT Id, Name FROM Contact WHERE AccountId = :acc.Id]; // This will cause the error if there are more than 100 accounts }
Recursive Triggers
Triggers that call themselves during processing can quickly multiply the number of queries executed, leading to this error.
Inefficient Code Structure
Poor code organization where the same data is queried multiple times instead of being stored and reused.
Complex Automation Chains
When multiple processes, workflows, or process builders trigger each other, each potentially executing their own SOQL queries.
How to Handle the Too Many SOQL Queries: 101 Error
1. Move SOQL Queries Outside of Loops
Instead of querying in loops, use collections and relationships:
apex// Bad approach for (Account acc : accountList) { List<Contact> contacts = [SELECT Id FROM Contact WHERE AccountId = :acc.Id]; } // Good approach Map<Id, Account> accountMap = new Map<Id, Account>( [SELECT Id, (SELECT Id FROM Contacts) FROM Account WHERE Id IN :accountIdList] );
2. Use Relationship Queries
Leverage parent-child relationship queries to get related data in a single query:
apex// Get accounts with their related contacts in one query List<Account> accountsWithContacts = [ SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account WHERE Id IN :accountIds ];
3. Implement Batch Apex for Large Datasets
When processing large volumes of data, consider using Batch Apex which processes records in smaller chunks:
apexpublic class ContactBatchProcessor implements Database.Batchable<sObject> { public Database.QueryLocator start(Database.BatchableContext bc) { return Database.getQueryLocator('SELECT Id FROM Account'); } public void execute(Database.BatchableContext bc, List<Account> scope) { // Process accounts in batches } public void finish(Database.BatchableContext bc) { // Final operations } }
4. Use Maps for Data Organization
Organize related data in maps to avoid redundant queries:
apex// Get all contacts for multiple accounts at once List<Contact> allContacts = [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds]; Map<Id, List<Contact>> contactsByAccountId = new Map<Id, List<Contact>>(); for (Contact c : allContacts) { if (!contactsByAccountId.containsKey(c.AccountId)) { contactsByAccountId.put(c.AccountId, new List<Contact>()); } contactsByAccountId.get(c.AccountId).add(c); }
Conclusion
The SOQL 101 error is a common challenge in Salesforce development that appears when your code exceeds the governor limit of 100 SOQL queries per transaction.
By following best practices like keeping queries outside loops, using relationship queries, implementing batch processing for large datasets, and organizing data effectively, you can avoid hitting this limit while creating more efficient and scalable applications.
Remember that this is a hard limit that cannot be increased by contacting Salesforce support, so optimizing your code is the only solution.