7.4 Governor Limits & Transaction Boundaries

Key Takeaways

  • Governor limits are platform-enforced multi-tenant protections that cap work per Apex transaction so one tenant cannot starve others
  • Key synchronous limits candidates memorize: 100 SOQL queries, 50,000 SOQL rows, 150 DML statements, 10,000 DML rows, 10,000 ms CPU, 6 MB heap, 100 callouts—verify current Apex Developer Guide if Salesforce revises numbers
  • Async Apex (Queueable, Batch, future, scheduled) often receives higher limits for some resources; still design bulk-safe code
  • A transaction boundary is one atomic unit of work—request, trigger cascade, or async job execution—limits reset at each new transaction
  • LimitException ends the transaction when a limit is exceeded; bulkification (collections, single query/DML patterns) is the primary defense
Last updated: August 2026

7.4 Governor Limits & Transaction Boundaries

Quick Answer: Salesforce enforces governor limits on each Apex transaction so multi-tenant neighbors stay safe. For synchronous work, memorize the classic ceilings: 100 SOQL queries, 50,000 SOQL rows, 150 DML statements, 10,000 DML rows, 10,000 ms CPU, 6 MB heap, 100 callouts (plus related limits). Exceeding a limit throws LimitException and aborts the unit of work. Bulkification keeps real triggers under these caps. Always treat published numbers as platform rules worth re-checking in the current Apex Developer Guide if Salesforce revises them.

This section explains why sections 7.1–7.3 obsess over one-query / one-DML patterns. Limits are not trivia—they are the operating system of Lightning Platform.

Why Limits Exist (Multi-Tenant Protection)

Salesforce runs many customers on shared infrastructure. Without per-transaction caps, one runaway trigger (SOQL in a loop over millions of rows, infinite recursion, huge heap) could degrade the instance. Governors are hard platform rules, not style suggestions. Code that “works for one record in the UI” can fail on a Data Loader insert of 200 rows—exactly the scenario exams simulate.

Key Synchronous Per-Transaction Limits

Candidates should know these synchronous figures as commonly tested baselines. If Salesforce updates documentation, prefer the current Apex Developer Guide—the exam and this guide use the long-standing teaching set below.

ResourceTypical synchronous limitWhat burns it
Total SOQL queries100Each SOQL statement (including those in loops!)
Total records retrieved by SOQL50,000Rows returned across queries (including subquery rows)
Total DML statements150Each insert/update/upsert/delete/undelete statement
Total records processed by DML10,000Sum of rows in DML operations
Maximum CPU time10,000 msApex CPU (not pure wait on callouts the same way)
Maximum heap size6 MBIn-memory collections, strings, queried rows
Maximum callouts100HTTP callouts per transaction

Related limits you should recognize by name even if exact secondary numbers vary by release/context:

  • SOSL queries per transaction (much lower than SOQL count)
  • Aggregate query row implications toward retrieval totals
  • Email invocations, push notifications, future calls, Queueable chain depth
  • Batch Apex scope sizes and per-execute limits

Teaching mnemonic: Queries (100) and DML statements (150) are about how many times you talk to the database. Rows (50k / 10k) are about how much data you move. CPU and heap are about how hard Apex works in memory.

Reading limits in code

System.debug('SOQL queries used: ' + Limits.getQueries() + ' / ' + Limits.getLimitQueries());
System.debug('DML statements used: ' + Limits.getDmlStatements() + ' / ' + Limits.getLimitDmlStatements());
System.debug('CPU time: ' + Limits.getCpuTime() + ' / ' + Limits.getLimitCpuTime());
System.debug('Heap: ' + Limits.getHeapSize() + ' / ' + Limits.getLimitHeapSize());

Use Limits methods in diagnostics—not as a substitute for bulk design. Polling limits in production paths is rare; designing so you stay far under caps is the goal.

Async Differences (High Level)

Asynchronous executions—@future, Queueable, Batch Apex execute, Schedulable jobs—often receive higher limits for some resources (for example, higher SOQL row or heap ceilings in async contexts). That does not mean you can SOQL-in-a-loop safely. Batch Apex is the platform tool for millions of rows: each execute is its own transaction with its own governors, scoped by batch size.

ContextMental model
Synchronous (UI, Lightning controller, trigger from interactive DML)Tightest common teaching limits (table above)
Async single transaction (future/Queueable)Often more headroom; still one transaction’s caps
Batch executeChunked transactions; design per-scope bulk patterns

Callouts + DML ordering: You cannot make a callout after uncommitted DML in the same transaction without careful patterns; async is often used to separate callout work. Limits and order-of-operations interact—another reason transaction boundaries matter.

Transaction Boundaries

A transaction is the atomic unit where:

  • Governors accumulate from zero to their caps
  • Successful completion commits DML together
  • Failure / unhandled exception / LimitException rolls back work for that transaction (unless handled with partial patterns/savepoints carefully)

Examples of boundaries:

  1. A Lightning action that runs Apex and finishes.
  2. A trigger-bearing insert of 200 Accounts from the API—one transaction for that batch, including all automation (before/after triggers, flows in the same invocation path, etc., as order of execution defines).
  3. Each Queueable execute method run.
  4. Each Batch Apex execute chunk.

Critical insight: Static variables reset between transactions but persist across trigger recursions within the same transaction—used for recursion control, not for long-term storage. Limits also accumulate across those recursive trigger firings in the same transaction. Bulkifying reduces statements; static flags stop infinite re-entry.

public class AccountTriggerHandler {
    private static Boolean ran = false;
    public static void afterUpdate(List<Account> news) {
        if (ran) return;
        ran = true;
        // safe bulk work once per transaction
    }
}

LimitException

When code exceeds a governor, the platform throws a System.LimitException (message indicates which limit). You generally cannot catch LimitException to keep going usefully—the transaction is in a failed state for continuing the same work. Design to prevent the exception:

  • Fewer SOQL/DML statements via collections
  • Selective filters and LIMITs when full tables are unnecessary
  • Batch/Queueable for volume beyond interactive transactions
  • Lean heap: avoid holding giant strings/lists longer than needed

Exam questions often show a loop with SOQL and ask what fails first: Too many SOQL queries: 101 is the iconic error string pattern.

How Bulkification Avoids Limits

Anti-patternLimit hitFix
SOQL per Trigger.new rowSOQL queries 100One query with IN :idSet
DML per rowDML statements 150One update list
Querying huge unbounded tables into a listHeap 6 MB / rows 50kSOQL-for loop, selective WHERE, Batch
Nested loops with expensive string work on large listsCPU 10sMaps, fewer iterations, move heavy work async
Callout per record in a loop of 200Callouts 100Aggregate callouts, bulk APIs, Queueable chaining carefully

Worked mini-scenario

Data Loader inserts 200 Contacts. Trigger runs once with Trigger.new.size() == 200.

  • Bad: 200 SOQL + 200 DML → fails SOQL or DML statement limits.
  • Good: 1 SOQL for related Accounts + 1 DML update on Contacts → uses 2 database statements for statements-count purposes (plus whatever else automation adds), well under 100/150.

Remember: other automation (Flow, rollups, package code) shares the same transaction limits. Defensive bulk code leaves headroom.

Practical Exam Strategy

  1. Count statements in the worst-case batch (usually 200 records).
  2. Spot SOQL/DML inside for immediately—almost always wrong.
  3. Prefer maps and sets in answers that scale.
  4. Know when to recommend Batch Apex vs a synchronous trigger solution.
  5. Treat limit numbers as platform-enforced multi-tenant protections, and note that official docs win if Salesforce revises a figure between your study guide and exam day.

Connecting 7.1–7.4

  • SOQL skills load data efficiently (relationship queries, binds, SOQL-for loops).
  • SOSL skills search text without fake multi-object SOQL.
  • DML skills persist changes with bulk lists and correct allOrNone behavior.
  • Governors are the scoring rubric the platform applies to all of the above.

If you can look at any Apex snippet and predict which governor breaks first—and rewrite it to collect, query once, DML once—you are operating at Platform Developer I level for data access.

Test Your Knowledge

Which set correctly lists commonly tested synchronous per-transaction Apex governor limits?

A
B
C
D
Test Your Knowledge

A trigger performs one SOQL query inside a for loop for each of 200 records in Trigger.new. What is the most likely outcome?

A
B
C
D
Test Your Knowledge

What is an Apex transaction boundary in the context of governor limits?

A
B
C
D