Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
All errors
Governor limits

System.LimitException: Too many SOQL queries: 101

Your code ran more than 100 SOQL queries in a single transaction. Almost always a SELECT inside a loop instead of one query whose results you iterate.

Also seen asToo many SOQL queries: 101·FATAL_ERROR System.LimitException: Too many SOQL queries: 101·LimitException: Too many SOQL queries

This is the most-Googled error in Salesforce history, and the cause is almost always the same: a SELECT sitting inside a for loop. Salesforce caps a single synchronous transaction at 100 SOQL queries; query 101 throws this LimitException and the whole transaction rolls back.

The shape of the bug

// One query per Account. The moment Trigger.new has 101 records, you are dead.
for (Account a : Trigger.new) {
    List<Contact> kids = [SELECT Id FROM Contact WHERE AccountId = :a.Id];
    a.Contact_Count__c = kids.size();
}

The shape of the fix

Lift the query out of the loop. Query once, group by parent ID into a Map, then iterate.

Set<Id> accountIds = new Map<Id, Account>(Trigger.new).keySet();

Map<Id, Integer> countByAccount = new Map<Id, Integer>();
for (AggregateResult ar : [
    SELECT AccountId, COUNT(Id) c
    FROM Contact
    WHERE AccountId IN :accountIds
    GROUP BY AccountId
]) {
    countByAccount.put((Id) ar.get('AccountId'), (Integer) ar.get('c'));
}

for (Account a : Trigger.new) {
    Integer c = countByAccount.get(a.Id);
    a.Contact_Count__c = c == null ? 0 : c;
}

One query, regardless of trigger size. This pattern is called bulkification and it is the single most important habit to build in Apex.

When 100 still isn't enough

If you legitimately need more than 100 queries in one logical operation, you have three escape hatches:

  1. Batch Apex. Each chunk processed by execute() gets its own fresh 100-query budget.
  2. Asynchronous queueables chained together. Each enqueueJob starts a new transaction.
  3. A different query. Often "I need 101 queries" really means "I haven't joined the data correctly" — a relationship query or GROUP BY collapses the problem.

Diagnose it from a debug log

Reproduce in a sandbox, open the failing transaction in Setup → Debug Logs, and search for SOQL_EXECUTE_BEGIN. Count them. If the same query string repeats dozens of times with only the bind parameter changing, you found your loop.

You can also instrument the running code:

System.debug('SOQL used: ' + Limits.getQueries() + ' / ' + Limits.getLimitQueries());

A nuance most people miss

The 100 cap is per transaction, not per script. A single Database.insert(records) can cascade into half a dozen triggers, workflow updates, and process automations — and they all share the same 100-query budget. So the runaway query may not be in your code at all; it may be in a trigger your code accidentally daisy-chained into. When you can't find the loop locally, look one level out at what your DML kicks off.

Related dictionary terms