Apex General

How to resolve System.LimitException: Too many SOQL queries: 101 in Apex?

How to fix System.LimitException: Too many SOQL queries: 101 in Apex

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.

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.

Shubham Lashkan

Shubham Lashkan is a Salesforce Developer at Advanz101 with four years of experience. He's worked on various Sales Cloud projects and integrations with platforms like Facebook, Jira, and Twitter. He regularly shares his knowledge through articles and videos on his blog, YouTube channel, and Apex Hours.

Leave a comment

Your email address will not be published. Required fields are marked *