Beginner 20 min read

Loops and Governor Limits

By the end of this lesson, you'll be able to:

  • Explain what a governor limit is and why Salesforce enforces them
  • Identify the classic mistake of putting a database operation inside a loop
  • Recognize bulk-safe code versus code that will fail at scale

Prerequisites: "Break and Continue"

What a governor limit is

Salesforce is a multi-tenant platform — many companies\' code runs on shared servers. To stop one org\'s runaway code from degrading performance for everyone else, Salesforce enforces hard limits per transaction: for example, at most 100 DML statements (inserts/updates/deletes) and 100 SOQL queries. Exceed one, and Apex throws a LimitException and the whole transaction fails.

The classic mistake: DML or queries inside a loop

// DON'T DO THIS
for (Account acc : accountsToUpdate) {
    acc.Industry = 'Technology';
    update acc; // a separate DML statement on every single iteration!
}
  1. // DON'T DO THIS — a comment flagging this as the anti-pattern, not something to copy.
  2. for (Account acc : accountsToUpdate) { — one pass per account.
  3. acc.Industry = 'Technology'; — changes a field in memory — harmless on its own.
  4. update acc; — a separate DML statement on every single iteration — this is the actual problem.
  5. } — closes the loop.

Warning: this looks harmless for 5 accounts. With 200 accounts, line 4 runs 200 times in one transaction — blowing past Salesforce's 100-DML-statement governor limit and throwing a LimitException that has nothing to do with the actual business logic.

The fix: bulkify — collect, then act once

List<Account> accountsToSave = new List<Account>();

for (Account acc : accountsToUpdate) {
    acc.Industry = 'Technology';
    accountsToSave.add(acc);
}

update accountsToSave; // one single DML statement, no matter how many accounts
  1. List<Account> accountsToSave = new List<Account>(); — an empty list to collect changed records.
  2. (blank line)
  3. for (Account acc : accountsToUpdate) { — one pass per account, same as before.
  4. acc.Industry = 'Technology'; — still just an in-memory change.
  5. accountsToSave.add(acc); — collects the changed record instead of saving it immediately.
  6. } — closes the loop — no DML has happened yet.
  7. (blank line)
  8. update accountsToSave; — one single DML statement, no matter how many accounts are in the list.

The loop now only modifies records in memory and collects them into a list; the actual update happens exactly once, after the loop, regardless of whether there are 5 accounts or 5,000. This pattern — "collect inside the loop, act once outside it" — is called bulkification, and it's one of the most important habits in all of Apex development.

A real business example: E-commerce (Order Fulfillment)

List<Order__c> ordersToShip = [SELECT Id, Status__c FROM Order__c WHERE Status__c = 'Ready'];

for (Order__c ord : ordersToShip) {
    ord.Status__c = 'Shipped';
}

update ordersToShip; // one DML statement updates every order at once
  1. List<Order__c> ordersToShip = [SELECT Id, Status__c FROM Order__c WHERE Status__c = 'Ready']; — one query, fetching every ready order at once.
  2. (blank line)
  3. for (Order__c ord : ordersToShip) { — one pass per order.
  4. ord.Status__c = 'Shipped'; — an in-memory change only.
  5. } — closes the loop.
  6. (blank line)
  7. update ordersToShip; — one DML statement updates every order at once, regardless of how many there are.

A daily batch job marking every ready order as shipped might process thousands of records at once — exactly the scenario where a query or DML statement inside the loop would fail immediately, and bulkified code keeps working no matter the volume.

Exercise

The code below updates a Description field inside a loop with a DML statement on every pass. Rewrite it to be bulk-safe: collect the changes, then update once after the loop.

Show hint

Move `update acc;` outside the loop and add each acc to a List<Account> instead.

Salesforce: ○ Not connected Connect
APEX

Execution Results

Run your code to see the result.

Loops and Governor Limits Quiz

1. Why does Salesforce enforce governor limits?

2. What is "bulkification"?

Log in to submit the quiz and save your score.

Leaderboard

  • 1. Monde Masiza 2/2

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

Salesforce runs on shared infrastructure, so every org's code is capped by governor limits — hard ceilings on things like database queries and DML statements — and loops are where those limits get hit hardest.