Learn Apex
Apex best practices
Governor limits reward code that does work in batches — not “one row at a time.” Play with the numbers below until the pattern clicks.
Playground

As a beginner, the fastest mental model is: your trigger or method might see 200 rows at once. If you write code that runs SOQL or DML once per row, you can exceed per-transaction limits in real data. The fix is almost always: collect, query once, map, then loop.

SOQL in a loop — drag the batch size

Synchronous transactions have a toy reference of 100 SOQL calls (real platform limits can differ by context — learn the official docs next).

Rows in trigger25
1200
Jump:

Anti-pattern

25

SOQL calls if you query once per row

Bar fills toward 100 SOQL (toy cap)

Better

1

One query with IN :ids then a map

Stays flat — scales with data, not row count

Avoid
// SOQL inside loop — count grows with Trigger.new.size()
for (Opportunity o : Trigger.new) {
    Account a = [SELECT Id, Name FROM Account WHERE Id = :o.AccountId LIMIT 1];
    o.Description = a != null ? a.Name : null;
}

DML in a loop — same batch size (25 rows)

Toy reference: 150 DML statements in a synchronous transaction (simplified).

update inside loop → 25 DML

one list update → 1 DML

Avoid
for (Contact c : contacts) {
    c.Description = 'x';
    update c; // one DML per row — dangerous at scale
}

Tap the bulk-safe snippet

Which version is bulk-safe for a trigger with many rows?

Habits — open one at a time

Collect Ids, query once into a Map, then walk your trigger data without SOQL inside for loops.

Next step: read Salesforce’s official governor limit tables for API, batch, and async contexts — the numbers change by context; this lesson is a training wheel, not the source of truth.