Governor Limits in Salesforce: Mastering 5 Critical Rules
Governor Limits in Salesforce: Mastering 5 Critical Rules
Blog Article
When you first start developing code in Salesforce, hitting a System.LimitException can feel like the platform is just putting up arbitrary roadblocks on your path. One is trying to build something powerful, and suddenly, one is told that one has used too many resources. It’s a common frustration, but it’s also your first real introduction to one of Salesforce’s core design principles: governor limits in Salesforce.
Thinking of these Salesforce Governor Limits as mere obstacles misses the point. They aren’t there to make your life difficult; they are the guardrails that keep the entire system stable and fast for everyone. Understanding why they exist is the first step from just writing code to building smart, scalable applications that can handle the demands of a real business. Let’s break down why these Salesforce Governor limits are in place, what they are, and how to build powerful solutions that work with them, not against them.
Why Salesforce Has Limits: How It Shares Resources
Salesforce is built on a concept called multi-tenancy. Imagine a massive apartment building where every Salesforce customer, from tiny startups to global corporations, has an apartment. Everyone shares the same foundation, plumbing, and electrical systems. This shared infrastructure is what makes Salesforce efficient. It allows for huge economies of scale and ensures that when a new feature is released, everyone gets it at the same time, all thanks to Salesforce governor limits.
But sharing resources creates a challenge. What if one tenant decides to run a massive, inefficient process that hogs all the server’s processing power or spams the database with endless queries? It would slow down the system for every other tenant in the building. This is the classic “noisy neighbor” problem, and governor limits in Salesforce are Salesforce’s solution.
These governor limits in Salesforce act as an automated management system, ensuring everyone gets their fair share of resources. They are the rules of the building that make sure one person’s runaway code doesn’t ruin the experience for everyone else. Each limit is carefully designed to protect a specific shared resource, guaranteeing a predictable and stable platform for all.
Types of Governor Limits
1. Per-Transaction Limits:
These are the limits you’ll encounter most often. For each Apex operation, your code gets a set allowance:
100 SOQL queries: How many times you can “ask the database for information.”
150 DML statements: How many times you can “make changes” (create, update, delete) to data.
10 seconds CPU time: Your code’s “thinking time.”
6MB heap size: Your code’s “workspace” (12MB for background tasks).
Hit any of these, and your code gets a runtime error.
2. Certified Managed Package Limits:
Apps from the Salesforce AppExchange often get their own, separate limits. This implies that trusted third-party code runs independently without having an impact on your organization’s custom limits.
3. Lightning Platform Apex Limits:
These are platform-wide limits, like the number of concurrent or queued jobs. They ensure that no single organization overwhelms Salesforce’s core processes, maintaining stability for everyone.
4. Static Apex Limits:
These are hardcoded limits in Apex that cannot be increased. Examples of Static Apex Limits include a maximum of 10 triggers per object or 1,000 records fetched by Database.getQueryLocator. They apply universally.
5. Size-Specific Apex Limits:
These involve handling of a large amount of data. These limits control data size, like the 6MB heap size or a 3MB cap on callout responses. They’re critical when working with large files or external integrations.
6. Miscellaneous Apex Limits: Key Details
These cover other vital areas: 5,000 emails per day, 20 HTTP callouts per transaction, or 10 queued jobs. Small but crucial in specific scenarios.
The Most Common Limits You’ll Encounter
Governor limits are typically enforced per transaction. A transaction is a single, complete unit of work, like an Apex trigger firing, a button click that calls an Apex method, or an API call. If your code exceeds a limit, Salesforce stops everything and rolls back the entire transaction to protect data integrity. Here are the main culprits you’ll run into:
- SOQL Queries: You are limited to 100 SOQL queries in a synchronous transaction (200 in asynchronous). It’s incredibly easy to hit this limit by placing a query inside a loop, a mistake many new developers make.
- DML Statements: You can only perform 150 DML operations (like insert, update, or delete) per transaction. Just like with queries, the key is to avoid performing DML on one record at a time. It’s far more efficient to update a list of 100 records in one go than to make 100 separate DML calls.
- Total Records: Beyond the number of operations, you’re also limited by volume. You can retrieve up to 50,000 records with SOQL and process up to 10,000 records with DML in a single transaction. This prevents a single process from trying to pull down or update the entire database at once.
- CPU Time: Your transaction has a limited amount of processing time—10 seconds for synchronous and 60 seconds for asynchronous operations. This isn’t just about your Apex code; it includes all the declarative automations like Flows and Process Builders that your code might trigger. Inefficient loops and complex logic can eat up this time quickly.
- Heap Size: This is the memory your transaction can use, capped at 6 MB (12 MB for async). Querying many fields on a large number of records or creating complex data structures in your code can quickly exhaust your memory allocation.
- Callouts: When integrating with external systems, you’re limited to 100 callouts per transaction, with a total timeout of 120 seconds. This ensures your code doesn’t get stuck waiting indefinitely for an outside service to respond.
The #1 Rule: Always Work with Lots of Data at Once
The single most important strategy for thriving within these governor limits is bulkification. This simply means writing your code to handle records in collections, not one by one. Since a trigger can be fired by an import of up to 200 records at once, bulk-safe code isn’t just a good idea—it’s essential for any real-world application.
The pattern is straightforward:
- Gather and Query: Collect all the IDs you need into a single List or Set. Then, run one SOQL query to grab all the necessary data at once.
- Process and Update: Loop through the records you retrieved in memory. Once you’ve made all your changes, perform a single DML statement on a list of records to save everything back to the database.
The Wrong Way: Handling One Record at a Time
This code is a classic example of what will break in production. It runs a query and a DML statement for every single record, quickly hitting governor limits.
Apex
// Anti-pattern: This will fail with more than a handful of records.
for (Account acc : Trigger.new) {
// A SOQL query INSIDE a loop is a major red flag.
Contact relatedContact = [SELECT Id FROM Contact WHERE AccountId = :acc.Id LIMIT 1];
// A DML statement INSIDE a loop is just as bad.
relatedContact.Description = 'This account was updated.';
update relatedContact;
}
The Right Way: Use the Bulk-Friendly Approach
This version is efficient and scalable. No matter how many records are in the trigger, it only ever uses one SOQL query and one DML statement.
Apex
// Best practice: Efficient, bulk-safe code
Set accountIds = Trigger.newMap.keySet();
// 1. Perform ONE query to get all the data you need.
List contactsToUpdate = [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds];
Map contactMap = new Map(contactsToUpdate);
// 2. Process the records in memory.
for (Id accountId : accountIds) {
Contact con = contactMap.get(accountId);
if (con != null) {
con.Description = 'Account has been updated.';
}
}
// 3. Perform ONE DML operation to save all changes.
update contactsToUpdate;
Handling a lot of Data: Asynchronous Apex
What if your task is just too big for regular governor limits? For things like nightly data processing or complex integrations, Salesforce provides asynchronous tools that run in the background with much higher governor limits.
- Future Methods (@future): The simplest way to run something in the background. Great for quick, isolated tasks like making a callout to an external service.
- Queueable Apex: More powerful than future methods, Queueable Apex lets you pass complex data types and, crucially, chain jobs together to handle sequential processes.
- Batch Apex: The go-to solution for processing thousands or millions of records. It breaks your data into manageable chunks and gives each chunk its own set of governor limits, allowing you to reliably work through massive datasets.
- Scheduled Apex: This allows you to schedule a job to run on a recurring basis—perfect for nightly cleanups, report generation, or any other routine maintenance.
Debugging Governor Limit Errors in Salesforce
Your Go-To Spot: The Developer Console and Debug Logs
So, you’re staring down a baffling governor limit error. Your first and best friend in this situation is always going to be the Salesforce Developer Console, especially when it’s teamed up with those detailed debug logs. This combo? It’s your mission control, giving you a play-by-play of literally everything that went down during your transaction. To make sense of it all, though, you’ve gotta know what signals to look for.
Inside that debug log, keep a close eye out for LIMIT_USAGE_FOR_NS entries. They give you a real-time snapshot of how much of a specific governor limit was used at various points in your code. By tracing these numbers, you can often pinpoint the exact line or even the section of code that’s pushing you over the edge. It’s also super smart to filter your logs for SOQL_EXECUTE_BEGIN and DML_BEGIN statements. These markers tell you precisely where your SOQL queries and DML operations are kicking off. This helps you spot inefficient loops or data access patterns that might be absolutely draining your limits. Seeing the sequence of these events alongside those LIMIT_USAGE_FOR_NS entries will usually, almost always, reveal the true culprit.
Get Savvy with the Limits Class:
Beyond the deep dive you get from the debug logs, Apex actually gives you a super powerful way to understand your current resource use directly within your code: it’s called the Limits class. This little gem offers a bunch of methods that let you check your current consumption against various governor limits right there as your code runs. For instance, Limits.getQueries() will tell you how many SOQL queries you’ve executed so far in the current transaction, and Limits.getDmlRows() shows you the number of DML rows you’ve processed.
Honestly, dropping Limits class methods into your code, especially when you’re in the middle of developing and testing, is a proactive move that can save you a ton of headaches. It helps you spot potential limit issues long before they become screaming critical errors. By strategically placing these calls, you get a real-time feel for how close you are to hitting a particular limit at different stages of your code’s execution. That kind of programmatic insight is just invaluable for fine-tuning your logic and making sure your code is as lean and streamlined as possible.
The Best Defense: Write Limit-Friendly Code from the Start
Okay, so being a great debugger is crucial, no doubt. But the absolute best way to handle governor limits is to just not hit them in the first place! If you adopt a proactive mindset and stick to some core best practices for writing limit-friendly code, you’ll dramatically cut down on these errors, and your life as a developer will just be so much smoother.
The “golden rule” of Salesforce development, the one you should tattoo on your brain, is to Bulkify! This means you should never ever put SOQL queries or DML statements inside a loop. That’s a primary, express lane to blowing through your SOQL query and DML row limits. Instead, get smart: use collections like a List or a Set to gather up all the IDs or data you need, and then perform a single, consolidated SOQL query or DML operation outside that loop. This drastically cuts down on the number of calls to the database and is fundamental for writing scalable code.
Always try to think in Sets and Maps when you’re dealing with related records. If you need to process info from parent or child records, use a Map<Id, SObject> to query all the necessary records in one shot. This lets you efficiently grab that related data within your loops using the record’s ID as the key, completely eliminating the need for those pesky, individual queries inside the loop.
Finally, for those super resource-intensive tasks that don’t need to happen instantly, consider asynchronous operations. Salesforce gives us some great options here like @future methods, Batch Apex, and Queueable Apex. These run in different contexts and, crucially, come with higher governor limits. That gives you way more breathing room for complex data processing, integrations, or calculations that might otherwise just crush your synchronous limits.
Using Governor Limits for Smart Coding
Salesforce governor limits aren’t just technical specs to memorize; they’re a framework that pushes you to become a better architect. They force you to think about efficiency, scalability, and the impact of your code on the entire system.
Learning to work within these governor limits transforms your perspective. You stop thinking about how to make something work for one record and start engineering solutions that perform flawlessly under a heavy, real-world load. In the end, the governor limits aren’t a wall; they’re a blueprint for building robust, elegant, and lasting applications on the Salesforce platform.
Understanding Governor Limits in Salesforce is crucial for building efficient, scalable, and high-performing applications. At AlmaMate Info Tech, we not only explain what these governor limits are—we train you to work within them like a pro.
Our Services Include:
- Salesforce Master Training Program – Learn how to design solutions that respect Governor Limits, with live projects and expert mentorship
- Salesforce Certification Guidance – Prepare for exams with a deep understanding of platform constraints and best practices
- Custom Salesforce Development – We build solutions that are limit-aware, efficient, and scalable
- Performance Optimization & Support – Post-deployment consulting to keep your org within limits while achieving maximum functionality
With 10,000+ professionals trained and a legacy of delivering Salesforce solutions that perform within platform governor limits, AlmaMate is your trusted partner in navigating Salesforce the smart way. Report this page