Read the screenplay: FANNIEGATE — $7 trillion. 17 years. The biggest fraud in American capital markets.
#6 ApexCareer-Ending

SOQL Query Inside a For Loop (The Classic)

Wrote a SOQL query inside a for loop. 200 records came in. 200 queries fired. Governor said no.

What Happened

Early in my Apex career, I wrote a trigger that queried the parent Account for each Contact in a bulk insert. I tested it with one record. Beautiful. Then a data migration pushed 200 Contacts at once. 200 SOQL queries. Governor limit hit at 101. The entire batch failed, the migration rolled back, and I spent the rest of the night rewriting the trigger while the data team waited.

The Wrong Way

trigger ContactTrigger on Contact (before insert) {
    for (Contact c : Trigger.new) {
        // SOQL INSIDE THE LOOP - NEVER DO THIS
        Account acc = [SELECT Id, BillingState
                       FROM Account
                       WHERE Id = :c.AccountId];
        c.Region__c = acc.BillingState;
    }
    // At 101 records: System.LimitException:
    // Too many SOQL queries: 101
}

The Right Way

trigger ContactTrigger on Contact (before insert) {
    // Collect all Account IDs first
    Set<Id> accountIds = new Set<Id>();
    for (Contact c : Trigger.new) {
        if (c.AccountId != null) {
            accountIds.add(c.AccountId);
        }
    }

    // ONE query for ALL accounts
    Map<Id, Account> accountMap = new Map<Id, Account>(
        [SELECT Id, BillingState FROM Account
         WHERE Id IN :accountIds]
    );

    // Now loop and use the map
    for (Contact c : Trigger.new) {
        Account acc = accountMap.get(c.AccountId);
        if (acc != null) {
            c.Region__c = acc.BillingState;
        }
    }
}

The Lesson

Bulkify or die. Collect IDs first, query once, use a Map. This is Apex 101 and I still catch experienced devs doing it in code reviews.

Don't make this mistake.

Hire someone who already did.

View Consulting →

Enjoyed this? Get more like it.

Glen's Musings — AI, investing, and building things. Occasional. Free.

More Apex Mistakes