Salesforce is built on a multi-tenant architecture, where thousands of organizations share the same infrastructure. To ensure fair resource allocation and prevent any single org from monopolizing CPU, memory, or database resources, Salesforce enforces governor limits. These are runtime restrictions on Apex code, Flows, and other processes. Exceeding a limit throws an unhandleable exception, halting the transaction.Think of it like an apartment building: everyone shares utilities, so limits prevent one tenant from using all the water or electricity.
Without limits:
- Poorly written code could crash servers
- One org could impact another Performance would degrade
Governor Limits enforce efficient and scalable development.
.png)
Types of Salesforce Governor Limits
Salesforce limits protect Three core system resources:
- Database → Control reads & writes
- CPU → Control execution time
- Heap → Control memory usage
Database Limits
Database Query Limits (Read Operations)
These limits protect Salesforce’s shared database from heavy reads.
SOQL Limits
- Synchronous - 100 SOQL queries (Per Transaction)
- Asynchronous - 200 SOQL queries (Per Transaction)
- Each transaction can return a maximum of 50,000 records
Important to know:
Even a single SOQL query can fail if it tries to return more than 50,000 records.
Common mistake:
Placing SOQL queries inside loops. This causes the query limit to be reached very quickly and often results in runtime errors.
Example: Send a welcome email to all Contacts related to newly created Accounts.
SOQL Inside a Loop (Bad Code)
.png)
Why this is a problem
- You have 50 Accounts
- The loop runs 50 times
- A SOQL query runs inside the loop
- Total SOQL queries = 50
- Add just a few more queries → Too many SOQL queries: 101
This code:
- Works in small test data
- Fails in real production
- Breaks Salesforce governor limits
Query Once, Loop Many (Correct Code)
.png)
Why this works
- Only 2 SOQL queries
- No queries inside loops
- Scales safely for bulk data
- Governor-limit friendly
SOSL Limits
- You can execute up to 20 SOSL queries (Per Transaction)
- Each transaction can return a maximum of 2,000 records
SOSL Inside a Loop (Bad Code)
.png)
Why this fails
- Loop runs 3 times (or more in real cases)
- One SOSL query per iteration
- With larger loops → Too many SOSL queries: 21
Database Write Limits (DML Operations)
Salesforce enforces DML limits to protect data integrity and maintain platform performance.
DML Limits
- You can execute up to 150 DML statements in a single transaction
- You can modify a maximum of 10,000 records (rows) per transaction
These limits apply regardless of whether the code is synchronous or asynchronous.
DML Inside a Loop(Bad Code)
.png)
Why this fails
- Loop runs 200 times
- One DML per iteration
- Total DML statements = 200
- Exception: Too many DML statements: 151
One DML Statement (Correct Code)
.png)
Why this works
- DML statements used: 1
- Records updated: 200
- Completely safe
Exceeding 10,000 Records (Bad Code)
.png)
Why this fails
- If accounts.size() > 10,000
- Even though it's 1 DML statement
- Exception: Too many DML rows: 10001
Bulkified DML (Correct Code)
Always collect records first, then perform one DML operation.
.png)
Handling Large Data Volumes (Correct Approach)
When you need to process more than 10,000 records, use Batch Apex or other asynchronous tools.
.png)
Why Batch Apex Works
- Processes records in small chunks (default 200)
- Each chunk is a separate transaction
- Avoids 10,000 row limit
- Safe for millions of records
Best Practice
When working with large volumes of data, always use Batch Apex (or other asynchronous processing) to split the workload into smaller, manageable chunks and stay within governor limits.
CPU Time Limits (Execution Time)
These limits control how long your code can run.
- Synchronous execution is limited to 10,000 milliseconds (10 seconds)
- Asynchronous execution is limited to 60,000 milliseconds (60 seconds)
Why CPU limits fail
- Nested loops
- Heavy calculations
- Large in-memory processing
- Complex flows
Memory (Heap Size) Limits
Heap size controls how much RAM your transaction can use.
- Synchronous execution is limited to 6 MB .
- Asynchronous execution is limited to 12 MB
What consumes heap
- Large lists/maps
- JSON parsing
- Debug logs
- Big query results
Other Limits
Asynchronous Execution Limits
- Future calls: 50
- Queueable jobs: 50
- Batch jobs queued: 5
- Scheduled jobs: 100
Important Rule
Never enqueue asynchronous jobs inside loops.
Doing so can quickly exceed governor limits and cause runtime failures.
Best Practices
- Combine records and process them in a single async job whenever possible
- Use Batch Apex for large data volumes
- Chain Queueable jobs carefully instead of enqueuing many at once
Email Limits : Salesforce enforces email and messaging limits to prevent spam, misuse, and performance issues across the platform.
Per Transaction
- Emails: 10
Per Day (Org)
- Single emails: 5,000
- Mass emails: License-based
Best Practices
- Avoid sending emails inside loops
- Consolidate notifications where possible
- Use scheduled or asynchronous processes for high-volume email needs
Flow-Specific Limits
Salesforce Flows follow the same governor limits as Apex, but they also introduce additional constraints specific to Flow execution.
Key Flow Limits
- A Flow can execute up to 2,000 elements in a single run
- Get Records elements count toward the SOQL query limits
- Create, Update, and Delete elements count toward DML limits
Common Flow Mistake
Placing multiple Get Records elements inside loops.
This causes SOQL limits to be reached very quickly and often results in Flow failures.
Best Practices
- Move Get Records elements outside of loops
- Retrieve all required records at once and loop over the results
- Minimize the number of Flow elements wherever possible
Reporting & Analytics Limits
Salesforce applies reporting and analytics limits to maintain performance and ensure reports load efficiently for all users.
Key Reporting Limits
- Reports can display up to 2,000 rows on screen
- Report exports are limited to 50,000 rows
- Dashboard refreshes are limited per user, based on edition and permissions
What This Means
- Large reports may not show all records when viewed online
- Exporting data is required when working with higher record volumes
- Excessive dashboard refreshes can be restricted to protect system performance
Best Practices
- Use report filters to reduce data volume
- Schedule dashboard refreshes instead of refreshing manually
- Break large reports into smaller, more focused ones
Conclusion
Governor Limits Are Not Restrictions They’re design guidelines.
Master them and you build:
- Scalable code
- Faster automations
- Production-ready solutions







.png)