Apex governors and namespaces

Platform governors prevent any one execution context from consuming excessive resources on the service, which could be detrimental to its users. Overall, an execution context cannot exceed 10 minutes, though within an execution context in practice, other limits would likely be reached before this.

For example, Apex code units executing within an execution context can only collectively execute for a maximum of 10 or 60 seconds depending on the context. Over the years, Salesforce has worked hard to consolidate what was once a confusing array of governors, which also varied based on a number of Apex code contexts. Thankfully, these days governors are much easier to follow and vary only based on the context being interactive or batch (asynchronous).

Namespaces and governor scope

An important consideration for a packaged solution is the scope of a governor. In other words, does it apply only to the packaged code or for all code executing in the execution context? Remember that an execution context can contain code from other developers within the subscriber org or other packaged solutions installed.

Your package namespace acts as a container for some governors, which protects your code from limits being consumed by other packaged code (triggers for example) running in the execution context. The platform supports an unlimited number of namespace scopes within one execution context. For code that has not been deployed as part of a managed package, such as code developed directly in the subscriber org, there is a default namespace.

Code running in a namespace cannot exceed governors that are scoped by the namespace (as highlighted later in this chapter). Although an execution context can run code from unlimited namespaces, a cross-namespace cumulative limit is enforced. This is 11 times the specific per namespace limit. For example, a maximum of 1650 DML statements (150 per namespace) would be allowed across any number of namespaces. For more examples refer to the Execution Governors and Limits page in the Apex Developer Guide, in the sub-section entitled Per-Transaction Certified Manage Package Limits.

Note

In reality 150 in my view is quite a lot of DML for a single namespace to be performing. If you are observing bulkification this would require you to be updating 150 distinct objects in one request! If that is the case and you are following DML bulkification, you may want to review your object model design to see if you can denormalize it a bit further. Though not documented, I suspect the 11 cumulative multiplier is likely based on the historic 10 namespace limit plus the default namespace.

You can see evidence of namespaces in play when you observe the debug logs within your packaging org. Just before each Apex code unit completes, notice how the LIMIT_USAGE_FOR_NS section of the debug log is repeated for the default and fforce namespaces (your namespace will be different) as follows, allowing you to review the incremental usage of governors throughout the execution context:

13:47:43.712 (412396000)|CUMULATIVE_LIMIT_USAGE
13:47:43.712|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 0 out of 150
  Number of DML rows: 0 out of 10000
  Number of code statements: 0 out of 200000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 10
  Number of Email Invocations: 0 out of 10
  Number of fields describes: 0 out of 100
  Number of record type describes: 0 out of 100
  Number of child relationships describes: 0 out of 100
  Number of picklist describes: 0 out of 100
  Number of future calls: 0 out of 10
13:47:43.712|LIMIT_USAGE_FOR_NS|fforce|
  Number of SOQL queries: 1 out of 100
  Number of query rows: 1 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 2 out of 150
  Number of DML rows: 3 out of 10000
  Number of code statements: 85 out of 200000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 10
  Number of Email Invocations: 0 out of 10
  Number of fields describes: 0 out of 100
  Number of record type describes: 0 out of 100
  Number of child relationships describes: 0 out of 100
  Number of picklist describes: 0 out of 100
  Number of future calls: 0 out of 10

13:47:43.712|CUMULATIVE_LIMIT_USAGE_END
13:47:43.412|CODE_UNIT_FINISHED|execute_anonymous_apex

Note that all governors are shown in the summary regardless of their scope; for example, the CPU time governor is an execution scope governor. This allows you to follow the consumption of the Apex CPU time across Apex code units from all namespaces. The Developer Console option provides some excellent tools to profile the consumption of governors.

Deterministic and non-deterministic governors

When considering governors from a testing and support perspective, you should be aware of which governors are deterministic and which are not. For example, when profiling your application, this is being able to obtain the exact same results (such as the preceding results) from the debug logs from the repeated running of the exact same test. The following outlines examples of both types of governors:

  • Examples of deterministic governors are the SOQL and DML governors. If you repeat the same test scenario (within your development or packaging orgs), you will always get the same utilization of queries and updates to the database; thus, you can determine reliably if any changes in these need to be investigated.
  • An example of a non-deterministic governor is the CPU time governor. The amount of time used between executions will vary based on the load at any given time on the Salesforce servers. Thus, it is hard to determine accurately whether changes in your application are truly affecting this or not. That being said, it can be a useful indicator depending on the variance you're seeing between builds of your software. However, keep in mind that the base line information you capture will become increasingly less accurate as time goes by, for example, between platform releases.

In the CPU governor, the platform limits the length of time the execution context is allowed to spend executing the Apex code to 10 seconds for interactive context and 60 seconds for asynchronous context (for example, Batch Apex), though in practice the platform appears to exercise some tolerance. In contrast, the number of SOQL queries or DML statements is always constant when applied to a consistent test scenario.

Note

As the CPU governor is non-deterministic, it should only be used as a guideline when testing. My recommendation is not to use the Limits.getCPULimit() method as a branching mechanism between interactive and batch processing in your application. If you require this type of branching, focus on using aspects of your application such as selection criteria, number of rows selected, or some other configurable setting in the subscriber org perhaps via a Custom Setting.

You may want to consider testing certain governors within an Apex test context to monitor for changes in how many queries or DML are being consumed. Such tests can give you an early warning sign that inefficiency has crept into your code. Use the Limits class methods to capture the before and after state of the SOQL and/or DML governors. Then, apply either a strict comparison of the expected usage (for example, 10 queries expected after the execution of the test) or a plus or minus tolerance to allow for code evolution.

Key governors for Apex package developers

The following table is a summary of key governors, their scope, and whether they are deterministic. Note that Salesforce is constantly monitoring the use of its service and adapting its governors. Always check for the latest information on governors in the Apex Developer Guide.

Governor

Scope

Deterministic

Execution context timeout

Execution context

No

Apex CPU governor

Execution context

No

SOQL queries

Namespace

Yes

DML statements

Namespace

Yes

Query rows

Namespace

Yes

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.177.85