In addition to the list posted by @AdrianLarson, there are other limits that you may need to be looking at in your code. You may also need to be reviewing to see if your code is testing to see if you're about to exceed a limit then preventing it from happening. This is particularly the case with asynchronous operations and can be used with other limits as well.
You can use the limits class to check things like getLimitQueueableJobs()
and getQueueableJobs()
to compare values and determine how close you are to exceeding limits before calling a new queuable. If close, you can abort/postpone the job if you don't have sufficient limits and create a mechanism to support that.
These are the kinds of practices you'll want to be looking for async code and in other code that may be part of service classes that are called frequently regardless of whether they occur in a loop. This is particularly true of email handlers (getEmailInvocations()
), web services (getLimitCallouts()
), batch operations that may use a lot of save points (getLimitSavepoints()
and getLimitSavepointRollbacks()
), and also could be important if you use Selector Classes that consume a lot of queries that can't cache results for reuse in maps (getLimitQueries()
).