The first error message that ever truly stopped me cold in Salesforce was something like “Too many SOQL queries: 101.” I had no idea what it meant or why my perfectly reasonable code had been shut down mid-run. It turned out I had bumped into a governor limit, and learning what those are is one of the most important steps a new Salesforce developer takes.
Let me explain what they are, why they exist, and the single mistake that causes most of the limit errors beginners run into.
Why limits exist at all
Salesforce is multi-tenant. That means your org does not run on its own private server. It shares infrastructure with many other customers, all running their code at the same time, on the same machines.
Think of an apartment building with shared plumbing. If one tenant decides to run every tap, shower, and hose at full blast, everyone else loses water pressure. So the building sets sensible limits, no single unit can hog the whole system. Governor limits are exactly that, rules that stop any one org’s code from consuming so many resources that it degrades the experience for everyone else in the building.
Governor limits are not Salesforce being stingy. They are the reason your org stays fast even though thousands of other companies share the same infrastructure.
Once you see limits as a feature that protects you rather than a wall that blocks you, they stop feeling adversarial. They are guardrails, and they push you toward writing efficient code, which you wanted to do anyway.
The limits you will meet first
There are many governor limits, but three account for most of the trouble beginners hit. All of them apply per transaction, meaning per single execution of your code.
SOQL queries per transaction. You can run up to 100 SOQL queries in a single synchronous transaction. That sounds like plenty, and it is, until you accidentally multiply your queries. More on that in a moment.
DML rows per transaction. DML is how you write to the database: insert, update, delete. You are capped at 10,000 records changed per transaction. Again, generous, until poorly structured code inflates the count.
CPU time per transaction. Your code gets a limited slice of processing time, 10 seconds for synchronous execution. Tight loops and heavy logic eat into this fast.
You do not need to memorize every number. You need to understand the shape of the rules: there is a ceiling on queries, on database writes, and on processing time, all measured per transaction.
The classic mistake: SOQL inside a loop
Now for the single error that catches nearly every beginner. It is putting a SOQL query inside a loop.
Here is what it looks like, and why it is so tempting:
// Do NOT do this
for (Contact c : contacts) {
Account a = [SELECT Name FROM Account WHERE Id = :c.AccountId];
// ... do something with a
}
This reads perfectly logically. For each contact, go fetch its account. The problem is that the query is inside the loop, so it runs once per contact. With 100 contacts, that is 100 queries. With 101, you have blown straight past the limit and your transaction dies with the exact error that stopped me years ago.
The fix is to pull the query out of the loop and fetch everything you need in one go, then work through the results in memory. That technique is the heart of writing safe Apex, and it deserves its own focused walkthrough, which is exactly what Bulkification gives you. If you take one habit from this article, let it be this: never put SOQL or DML inside a loop.
Where limits bite hardest
Governor limits feel abstract until you write a trigger. Remember that a trigger can receive up to 200 records at once. If your trigger queries inside a loop over those records, you have built a limit error that hides quietly until real data volume arrives.
This is why triggers and limits are taught together. A trigger that looks fine on one record can detonate on a batch import. If you have not yet read Apex Triggers Explained, it pairs directly with this topic, because triggers are where most beginners first feel a limit bite.
How to stay on the safe side
You do not need advanced techniques to respect limits early on. A few habits cover most cases.
Query once, outside your loops, and gather what you need up front. Collect records into a list and perform your inserts or updates in a single DML statement instead of one per record. And when you are unsure where your queries and DML are accumulating, the Developer Console shows you limit usage as your code runs, so you can watch the counters climb and catch a problem before it becomes an error.
When I was a guidance counselor, I learned that a small habit practiced early prevents a large problem later. The same is true here. Build the instinct to query and write in batches now, while your code is simple, and you will rarely meet these limits as your code grows.
Your next step
The natural follow-up is Bulkification, which turns “respect the limits” into concrete, repeatable patterns. Then revisit Apex Triggers Explained with limit-aware eyes, since triggers are where these lessons matter most. More awaits in the Foundations category.