Salesforce governor limits are runtime execution limits that prevent any single tenant from monopolizing shared resources in Salesforce’s multi-tenant architecture. These limits ensure consistent performance across all organizations by restricting resource consumption per transaction.
Understanding governor limits is critical for Salesforce developers, administrators, and architects. Exceeding these limits results in runtime exceptions that can break functionality in production environments.
What Are Salesforce Governor Limits?
Governor limits are Salesforce’s enforcement mechanism for resource allocation in the multi-tenant cloud platform. They prevent runaway code from consuming excessive CPU time, memory, or database resources that could impact other organizations sharing the same infrastructure.
These limits apply to all Apex code execution contexts including triggers, classes, batch jobs, scheduled jobs, and future methods. The limits reset at the beginning of each transaction and are tracked throughout the execution context.
Types of Salesforce Governor Limits
Salesforce enforces several categories of governor limits:
- Per-Transaction Limits: Apply to each Apex transaction (synchronous and asynchronous)
- Platform Limits: Organization-wide limits for API calls, storage, and features
- Static Limits: Code-level restrictions on class size, method complexity
- Push Topic Limits: Streaming API and platform event constraints
- Email Limits: Restrictions on email sending functionality
Per-Transaction Governor Limits (Winter ’26)
The following table shows the most critical per-transaction limits that Salesforce developers encounter in production environments:
| Description | Synchronous Limit | Asynchronous Limit |
|---|---|---|
| Total number of SOQL queries issued (excludes custom metadata types) | 100 | 200 |
| Total number of records retrieved by SOQL queries | 50,000 | |
| Total number of records retrieved by Database.getQueryLocator | 10,000 | |
| Total number of SOSL queries issued | 20 | |
| Total number of records retrieved by a single SOSL query | 2,000 | |
| Total number of DML statements issued | 150 | |
| Total number of records processed by DML statements, Approval.process, or Database.emptyRecycleBin | 10,000 | |
| Total stack depth for recursive trigger execution | 16 | |
| Total number of callouts (HTTP requests or Web services calls) | 100 | |
| Maximum timeout for all callouts in a transaction | 120 seconds | |
| Maximum number of methods with @future annotation per invocation | 50 | |
| Maximum number of Apex jobs added with System.enqueueJob | 50 | |
| Total number of sendEmail methods allowed | 10 | |
| Total heap size | 6 MB | 12 MB |
| Maximum CPU time on Salesforce servers | 10,000 milliseconds | 60,000 milliseconds |
| Maximum execution time for each Apex transaction | 10 minutes | |
| Maximum number of unique namespaces referenced | 10 | |
| Maximum number of push notification method calls | 10 | |
| Maximum push notifications per method call | 2,000 | |
Common Governor Limit Exceptions in Production
The most frequent governor limit violations in enterprise Salesforce implementations include:
SOQL Query Limits
The 100 synchronous SOQL query limit is commonly exceeded in poorly designed triggers and classes. Each SOQL statement counts toward this limit, including queries in loops.
// BAD: SOQL in loop - will hit governor limits
for (Account acc : accountList) {
List<Contact> contacts = [SELECT Id FROM Contact WHERE AccountId = :acc.Id];
}
// GOOD: Bulkified query outside loop
Set<Id> accountIds = new Set<Id>();
for (Account acc : accountList) {
accountIds.add(acc.Id);
}
Map<Id, List<Contact>> contactMap = new Map<Id, List<Contact>>();
for (Contact con : [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds]) {
if (!contactMap.containsKey(con.AccountId)) {
contactMap.put(con.AccountId, new List<Contact>());
}
contactMap.get(con.AccountId).add(con);
}
DML Statement Limits
The 150 DML statement limit applies to insert, update, delete, and upsert operations. Each DML statement counts regardless of how many records it processes.
// BAD: DML in loop
for (Account acc : accountList) {
update acc; // Each update counts as 1 DML statement
}
// GOOD: Bulk DML outside loop
update accountList; // Single DML statement for all records
CPU Time Limits
The 10-second CPU time limit for synchronous transactions is frequently exceeded by complex calculations, inefficient algorithms, or processing large data sets.
Best Practices for Avoiding Governor Limits
Bulkification Patterns
Always design Apex code to handle multiple records efficiently:
- Query data outside of loops using collections (Set, List, Map)
- Perform DML operations on collections, not individual records
- Use Map data structures for efficient lookups instead of nested loops
- Implement efficient sorting and filtering algorithms
Asynchronous Processing
Move long-running operations to asynchronous contexts with higher limits:
- Batch Apex: Process large data volumes with 200 SOQL queries and 60-second CPU time
- Queueable Apex: Chain jobs with monitoring capabilities
- Future Methods: Handle callouts and non-urgent processing
- Scheduled Apex: Run maintenance operations during off-peak hours
Query Optimization
Optimize SOQL queries to reduce resource consumption:
- Use selective WHERE clauses with indexed fields
- Limit result sets with LIMIT clauses
- Avoid unnecessary field selections
- Use relationship queries instead of multiple SOQL statements
- Implement query result caching where appropriate
Monitoring Governor Limits in Code
Use the Limits class to monitor resource consumption and implement defensive programming:
// Check SOQL query usage
System.debug('SOQL queries used: ' + Limits.getQueries() + ' of ' + Limits.getLimitQueries());
// Check DML statement usage
System.debug('DML statements used: ' + Limits.getDMLStatements() + ' of ' + Limits.getLimitDMLStatements());
// Check CPU time usage
System.debug('CPU time used: ' + Limits.getCpuTime() + ' of ' + Limits.getLimitCpuTime());
// Check heap size usage
System.debug('Heap size used: ' + Limits.getHeapSize() + ' of ' + Limits.getLimitHeapSize());
// Defensive programming example
if (Limits.getQueries() > 90) {
// Approaching SOQL limit - implement alternative logic
System.debug('Approaching SOQL query limit - switching to alternative processing');
}
Governor Limits in Different Execution Contexts
Trigger Context
Triggers share governor limits with the entire transaction, including workflow rules, process builder, and flows triggered by the same DML operation.
Batch Apex Context
Each batch execution gets fresh governor limits. The start(), execute(), and finish() methods each have separate limit tracking.
Test Context
Test methods have the same governor limits as synchronous Apex. Use Test.startTest() and Test.stopTest() to reset limits within test methods.
Integration Patterns and Governor Limits
When implementing Salesforce integration patterns, consider these governor limit implications:
REST API Integration
Callout limits (100 per transaction, 120-second timeout) affect REST API integrations. Use asynchronous processing for high-volume integrations.
Bulk API Integration
Bulk API operations don’t consume Apex governor limits but have their own rate limits and processing constraints.
Platform Events
Platform event publishing counts toward DML limits. Event processing in subscribers has separate governor limit tracking.
Security Considerations with Governor Limits
Governor limits provide inherent security benefits by preventing denial-of-service attacks through resource exhaustion. However, consider these security aspects:
- Implement proper input validation to prevent malicious data from causing limit violations
- Use sharing rules and field-level security to limit data access in queries
- Monitor governor limit violations in production for potential security incidents
- Implement circuit breaker patterns for external integrations
Troubleshooting Governor Limit Violations
When governor limit exceptions occur in production:
- Identify the specific limit: Check the exception message for the exact limit violated
- Review debug logs: Use System.debug statements and Limits class methods
- Analyze execution flow: Trace the code path leading to the violation
- Implement bulkification: Refactor code to handle multiple records efficiently
- Consider asynchronous processing: Move operations to contexts with higher limits
Quick Deploy Considerations
When using Salesforce quick deploy functionality, ensure your code adheres to governor limits:
- Test classes must not violate governor limits during deployment
- Bulk operations in deployment scripts should be properly bulkified
- Consider deployment order to avoid trigger recursion limit violations
- Use deployment monitoring to track governor limit consumption during large deployments
Frequently Asked Questions
What happens when Salesforce governor limits are exceeded?
When governor limits are exceeded, Salesforce throws a runtime exception that terminates the current transaction. All DML operations in the transaction are rolled back, and the user receives an error message. The specific exception type depends on which limit was violated (e.g., System.LimitException for SOQL queries).
How do I check governor limits in Apex code?
Use the Limits class methods to check current usage: Limits.getQueries() for SOQL queries, Limits.getDMLStatements() for DML operations, Limits.getCpuTime() for CPU time, and Limits.getHeapSize() for memory usage. Compare these values with their corresponding limit methods like Limits.getLimitQueries().
Do governor limits apply to Lightning Web Components?
Governor limits don’t directly apply to Lightning Web Components (LWC) JavaScript code. However, when LWCs call Apex methods through @wire or imperative calls, those Apex methods are subject to governor limits. Each server-side Apex call from an LWC starts a new transaction with fresh governor limits.
What are the differences between synchronous and asynchronous governor limits?
Asynchronous contexts (Batch Apex, Queueable, Future methods) have higher limits than synchronous execution. Key differences include: 200 vs 100 SOQL queries, 12MB vs 6MB heap size, and 60 seconds vs 10 seconds CPU time. These higher limits allow for more intensive processing in background operations.
How do Salesforce relationship queries affect governor limits?
Relationship queries (using dot notation like Account.Owner.Name) count as a single SOQL query regardless of how many relationship levels are traversed. However, they can return more records and consume more heap memory. Parent-to-child relationship queries (subqueries) also count as one SOQL query but are limited to 20,000 child records total across all parent records.
Can governor limits be increased for specific organizations?
Most governor limits are fixed and cannot be increased by Salesforce Support. However, some platform limits like API call limits can be increased through purchasing additional capacity or higher-tier licenses. The per-transaction Apex limits (SOQL, DML, CPU time) are not adjustable and must be worked around through proper code design.
For the most current governor limits and detailed specifications, refer to the official Salesforce Apex Developer Guide and the Salesforce Limits Quick Reference.