Study guide
7.4 Governor Limits & Transaction Boundaries
Salesforce Certified Platform Developer I Exam
Track your progress as you read
Finished sections get a check mark.
1 Introduction & Exam Overview
1.1 Current Exam Facts 1.2 Blueprint Weights & Study Strategy
2 Platform Fundamentals
2.1 Multi-Tenant Architecture & Shared Resources 2.2 MVC Mapping on the Lightning Platform 2.3 Declarative vs Programmatic Decisions 2.4 Agentforce for Developers: Use Cases & Limitations
3 Data Modeling & Schema
3.1 Objects, Fields & Schema Design 3.2 Relationship Types & Implications 3.3 Schema Design Impact on Apex 3.4 Data Import & Export for Development
4 Platform Data Features
4.1 Formula Fields & Roll-Up Summaries 4.2 Core CRM Objects & Standard Schema 4.3 AppExchange Extensions & Platform Boundaries
5 Declarative Process Automation
5.1 Record-Triggered Flows & Declarative Automation 5.2 Approval Processes & Business Rules 5.3 When to Use Apex vs Declarative Tools
6 Apex Language Basics
6.1 Variables, Constants & Apex Data Types 6.2 Lists, Sets & Maps 6.3 Control Flow & Exception Handling 6.4 Classes, Interfaces & OOP Patterns
7 SOQL, SOSL & DML
7.1 SOQL Query Fundamentals 7.2 SOSL Search Fundamentals 7.3 DML Operations & Bulkification 7.4 Governor Limits & Transaction Boundaries
8 Apex Triggers & Order of Execution
8.1 Trigger Structure & Context Variables 8.2 Bulk Trigger Patterns & Best Practices 8.3 Save Order of Execution 8.4 Recursion, Cascading & Transaction Control
9 Asynchronous Apex
9.1 @future Methods 9.2 Queueable Apex 9.3 Batch Apex 9.4 Schedulable Apex & Job Orchestration
10 Security, Events & Schema Access
10.1 Sharing, FLS, CRUD & Injection Prevention 10.2 Platform Events Publish & Subscribe 10.3 Programmatic Schema Access (Describe)
11 Visualforce
11.1 Visualforce Pages & Markup 11.2 Standard, Custom Controllers & Extensions 11.3 Visualforce in Lightning Experience
12 Lightning Components
12.1 Lightning Component Framework Benefits 12.2 Aura Component Structure & Resources 12.3 Lightning Web Components Fundamentals 12.4 LWC Data Access: Wire, Imperative & Events
13 UI Composition & Apex Integration Patterns
13.1 Composing UI in Lightning Apps 13.2 UI Security, Performance & Accessibility Patterns 13.3 Apex Actions for Flow, LWC, and Agentforce
14 Apex Testing
14.1 Testing Framework & Coverage Requirements 14.2 Writing Unit Tests for Triggers & Classes 14.3 Test Data Strategies & Isolation 14.4 Executing Tests & Execute Anonymous Differences
15 Debugging & Developer Tools
15.1 Debug Logs & Monitoring 15.2 Developer Console, CLI, VS Code & Workbench 15.3 Sandboxes, Scratch Orgs & Environment Strategy
16 Deployment & Release
16.1 Change Sets & Metadata Deployment 16.2 Unlocked Packages, Metadata API & Salesforce DX 16.3 Release Readiness & Credential Maintenance
7.4 Governor Limits & Transaction Boundaries
Key Takeaways Explain This Topic AI
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.
- Resource Typical synchronous limit What burns it
- Total SOQL queries 100 Each SOQL statement (including those in loops!)
- Total records retrieved by SOQL 50,000 Rows returned across queries (including subquery rows)
- Total DML statements 150 Each insert/update/upsert/delete/undelete statement
- Total records processed by DML 10,000 Sum of rows in DML operations
- Maximum CPU time 10,000 ms Apex CPU (not pure wait on callouts the same way)
- Maximum heap size 6 MB In-memory collections, strings, queried rows
- Maximum callouts 100 HTTP 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.
Context Mental 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 execute Chunked 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:
A Lightning action that runs Apex and finishes.
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).
Each Queueable execute method run.
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-pattern Limit hit Fix
- SOQL per Trigger.new row SOQL queries 100 One query with IN :idSet
- DML per row DML statements 150 One update list
- Querying huge unbounded tables into a list Heap 6 MB / rows 50k SOQL-for loop, selective WHERE, Batch
- Nested loops with expensive string work on large lists CPU 10s Maps, fewer iterations, move heavy work async
- Callout per record in a loop of 200 Callouts 100 Aggregate 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
Count statements in the worst-case batch (usually 200 records).
Spot SOQL/DML inside for immediately—almost always wrong.
Prefer maps and sets in answers that scale.
Know when to recommend Batch Apex vs a synchronous trigger solution.
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.