Salesforce governor limits are enforced per transaction to protect the shared multitenant platform from any single customer's code monopolising resources. They are not bugs, and they cannot be negotiated away. But hitting them in production is always a code quality problem, not a platform limitation problem. Every governor limit violation that surfaces in production was detectable — in the sandbox, in static analysis, in a code review — before it went live. Understanding the most common Salesforce governor limits and the patterns that cause them turns a production incident waiting to happen into a design standard your team follows from day one.

The Key Governor Limits You Need to Know

LimitSynchronousAsynchronousMost Common Violation
SOQL queries100200SOQL inside a loop
DML statements150150DML inside a loop
Records per DML10,00010,000Batch size misconfiguration
CPU time10,000ms60,000msComplex nested loops, string manipulation
Heap size6 MB12 MBLarge SObject collections in memory
Callouts per transaction100100Callouts in loops
Future methods per transaction50Spawning @future inside loops

The Cardinal Sin: SOQL and DML Inside Loops

The SOQL-in-a-loop violation is the most widespread governor limit problem in Salesforce Apex, and it surfaces almost exclusively in production under bulk load conditions. The pattern looks like this:

A trigger fires on Account update. The trigger iterates over Trigger.new and, for each Account, queries all related Contacts: SELECT Id FROM Contact WHERE AccountId = :acc.Id. In a developer sandbox with one record being updated at a time, this fires once — one SOQL query. In production, when an integration batch-updates 100 Accounts simultaneously, the same trigger fires 100 SOQL queries in a single transaction, immediately hitting the 100-query limit and throwing a System.LimitException.

The fix — called bulkification — is to collect all Account IDs before the loop, run a single SOQL query for all related Contacts using an IN clause, store the results in a Map, and then reference the Map inside the loop:

Bulkified pattern: Collect IDs → one SOQL query → Map<Id, List<SObject>> → iterate Map in loop → collect DML in List → one DML after loop

The same principle applies to DML. Never call update record inside a loop. Collect all records that need updating into a List, and call update recordList once after the loop exits.

Asynchronous Processing as a Governor Limit Strategy

Some operations genuinely require more resources than synchronous governor limits allow. The answer is not to try to optimise within synchronous limits — it is to move the operation to an asynchronous context where higher limits apply and the platform handles scheduling.

The four async processing frameworks, and when to use each:

Flow Automation and Governor Limits

Flow automation interacts with governor limits in ways that are less visible than Apex but equally consequential. Record-triggered flows are subject to the same per-transaction limits as Apex triggers — a flow that queries related records in a loop will hit the SOQL limit just as reliably as an Apex trigger doing the same thing. The difference is that flow violations are harder to detect in advance because flows do not have the same static analysis tooling as Apex.

Two common flow governor limit patterns to audit:

Governor limit violations hiding in your org?

SproutEzee gives you production-representative sandbox environments where realistic data volumes surface limit violations before go-live — not after.

See SproutEzee →

Frequently Asked Questions

What are the most commonly hit Salesforce governor limits in production?

The most common are: SOQL query limit (100 synchronous) — hit by SOQL inside loops; DML statement limit (150) — hit by DML inside loops; CPU time limit (10,000ms synchronous) — hit by complex automation chains; heap size limit (6 MB synchronous) — hit by large collections in memory; and daily API call limits — hit by integrations making individual calls per record instead of batching.

How do you fix SOQL queries inside loops in Salesforce Apex?

Bulkify your code: collect the set of IDs before the loop, perform a single SOQL query using an IN clause, store results in a Map keyed by ID, and access the Map inside the loop. This reduces N queries to 1 query regardless of batch size. The same pattern applies to DML — collect records in a List and issue one DML after the loop.

Why do governor limits feel worse in production than in sandbox?

Transactions in production process more records simultaneously. A trigger built for single-record updates works fine in sandbox. In production, a bulk integration posting 200 records fires the same trigger with 200 records in one transaction. SOQL-in-a-loop that ran 1 query in sandbox now runs 200, immediately hitting the limit. Sandbox tests rarely reveal this; production always will.

What tools can help identify governor limit issues before production?

The Developer Console's Limits tab during Apex execution, Apex log analysis via the Tooling API, static analysis with PMD's Apex ruleset, and running automated tests in a partial sandbox with realistic data volumes. Realistic sandbox data is the most reliable way to surface limit violations before go-live.

Can Salesforce governor limits be increased or bypassed?

Most cannot be permanently increased — they are a feature of the multitenant architecture. Salesforce support can increase API call daily limits with a business justification. The correct approach is designing code that does not approach existing limits. Asynchronous processing (Batch Apex, Queueable, @future) provides higher limits for operations that do not need to be synchronous.