Skip to main content

Mastering Salesforce Apex Governor Limits: Common Exceptions & Mitigation Strategies

Updated Add a comment
In plain words: Governor Limits are Salesforce's traffic rules for multi-tenant architecture. Because many companies share the same underlying cloud infrastructure, Salesforce enforces strict transaction caps (like memory, queries, and CPU time) so one piece of inefficient code cannot slow down or crash the shared platform.

Salesforce executes Apex code in a multi-tenant cloud environment. To guarantee high performance, platform stability, and fair resource sharing, the runtime engine enforces strict per-transaction limits known as Governor Limits. When code exceeds these boundaries, Salesforce throws a fatal runtime LimitException that immediately halts execution. Writing resilient Apex requires a clear understanding of these boundaries and defensive design patterns.

1. Understanding Core Governor Limits

Governor limits monitor resources across synchronous and asynchronous transactions. Understanding these thresholds is essential for designing high-throughput triggers, batch jobs, and APIs.

360 Governor Limits Quick Reference Card:
  • Total SOQL Queries: 100 (Synchronous) / 200 (Asynchronous).
  • Total Records Retrieved via SOQL: 50,000 across all queries in a single transaction.
  • Total DML Statements: 150 statements modifying up to 10,000 total records.
  • Maximum CPU Time: 10,000 ms (Synchronous) / 60,000 ms (Asynchronous).
  • Total Heap Size (Memory): 6 MB (Synchronous) / 12 MB (Asynchronous).
  • Concurrent Long-Running Requests: 10 requests lasting longer than 5 seconds.

2. Top Governor Limit Exceptions & Why They Occur

  • System.LimitException: Too many SOQL queries: 101: Caused by placing SOQL queries inside for loops rather than querying parent-child relationships or using collection binding outside loops.
  • System.LimitException: Apex CPU time limit exceeded: Triggers when long-running nested loops, heavy regular expressions, or recursive trigger handlers consume more than 10 seconds of processing time.
  • System.LimitException: Apex heap size too large: Occurs when large datasets or memory-heavy JSON strings exceed available RAM allocations.
  • System.LimitException: Too many DML statements: 151: Caused by invoking individual DML operations (such as insert or update) on single records inside iteration blocks instead of batching lists.

3. Defensive Coding Patterns: Bulkification & Safe Limits

To avoid hitting hard limits, write bulkified code that batches database operations and monitors resource consumption before executing heavy logic.

Real-World Example: Proactive Limit Checking & Bulk DML
Inspecting CPU time and remaining SOQL capacity dynamically using the Limits class:
public with sharing class CaseResolutionService {
    public static void resolveCasesBulk(Set<Id> caseIds) {
        if (caseIds == null || caseIds.isEmpty()) {
            return;
        }

        // 1. Proactive Limit Inspection
        if (Limits.getQueries() >= Limits.getLimitQueries() - 5) {
            System.debug(LoggingLevel.WARN, 'SOQL limit nearing capacity. Offloading to Queueable.');
            System.enqueueJob(new AsyncCaseProcessor(caseIds));
            return;
        }

        // 2. Single SOQL Query outside loops with User Mode enforcement
        List<Case> casesToUpdate = new List<Case>();
        for (Case c : [SELECT Id, Status, Priority FROM Case WHERE Id IN :caseIds WITH USER_MODE]) {
            if (c.Status != 'Closed') {
                c.Status = 'Closed';
                casesToUpdate.add(c);
            }
        }

        // 3. Single Bulk DML Operation
        if (!casesToUpdate.isEmpty()) {
            Database.update(casesToUpdate, false, AccessLevel.USER_MODE);
        }
    }
}

4. Offloading Heavy Work with Asynchronous Apex

When synchronous transactions approach CPU or heap constraints, delegating work to asynchronous frameworks increases processing headroom significantly.

  • Queueable Apex: Ideal for complex business processes, chaining jobs, and invoking external REST callouts with elevated limits (60,000 ms CPU and 12 MB Heap).
  • Batch Apex: Splits millions of records into manageable chunks (typically 200 records per execution scope), resetting governor limits for each batch execution.
  • SOQL For Loops: Use chunked iteration syntax (for (List<Account> accBatch : [SELECT Id FROM Account])) to process up to 50,000 records without exceeding the heap size limit.

5. Architectural Traps & Best Practices

Developer Trap: Uncatchable Limit Exceptions
A common misconception is that try-catch blocks can catch Governor Limit Exceptions. System.LimitException cannot be caught in Apex; the entire transaction rolls back immediately upon violation. Prevention through bulkification and proactive Limits checking is your only defense.
Core Rule: Never execute SOQL queries or DML statements inside loops. Always collect record IDs into Sets, query once outside the loop, and perform bulk DML on Lists.
  • Trim SOQL Projections: Never query unnecessary fields. Fetching only required columns reduces heap consumption and optimizes database response times.
  • Implement Trigger Frameworks: Prevent recursive triggers and duplicate DML executions by managing context state with static Boolean flags or standardized trigger handler frameworks.
  • Clear Unused Heap References: Set large collections or temporary data structures to null when they are no longer needed to free heap space during long-running tasks.

Summary

Governor Limits are essential to maintaining performance and stability across Salesforce's multi-tenant architecture. By adopting bulkified design patterns, offloading complex tasks to Queueable or Batch Apex, and monitoring consumption with the Limits class, you can build reliable enterprise applications that scale effortlessly without runtime interruptions.

Was this article helpful?

Have a question or spotted a mistake? Ask here about this article

Found this guide useful? Buy me a coffee (opens in a new tab)

Comments

Questions, corrections and your own experience are all welcome.