03 February 2016

Quiddity - the 'whatness' of concurrent Apex limits in Event Monitoring

Quiddity.

I had to look that one up. One of our awesome architects here at Salesforce, Peter Wisnovsky, came up with it.

Quiddity is defined by Wikipedia as the essence of an object. Literally its "whatness" or "what it is".

What the?! Why not just call it 'type', 'category', or 'dimension'? I asked Peter and he told me that 'type' was too overloaded. I personally just think it's because 'type' was too boring whereas 'quiddity' is supercalifragilisticexpialidocious!

Regardless it turns out that understanding an Apex class's quiddity is pretty important when determining whether you've hit the synchronous concurrent Apex limit.

From the Apex Developer's Guide,
"The Concurrent Apex Limit is the number of synchronous concurrent requests for long-running requests that last longer than 5 seconds for each organization. If more requests are made while the 10 long-running requests are still running, they’re denied. Of which, each org has a limit of 10."
What this really means is that when the limit is exceeded, users may receive the following error which can seem confusing to an end-user or even an admin:
"Unable to Process Request.  Concurrent requests limit exceeded.
To protect all customers from excessive usage and Denial of Service attacks, we limit the number of long-running requests that are processed at the same time by an organization. Your request has been denied because this limit has been exceeded by your organization. Please try your request again later."
There's a great blog post on the engineering developer blog by the former blimp pilot, John Tan, that goes into more detail about what this limit is and how to work with it.

The quiddity log attribute is key to unlocking an Event Monitoring query to find out which Apex classes have the potential to hit the concurrent Apex limit in your org. Well, that's pretty darn useful, so we added the quiddity attribute to the ApexExecution file type in the Spring '16 release.

There are two reasons why you might run into the concurrent Apex limit:
1. High callout time <--- Probably the most common cause!
2. High database time

If the cause was a high callout time, you can filter your ApexExecution file based on QUIDDITY (E, H, M, R, V, W, X, L, K, or I) and CALLOUT_TIME (>5000), both of which were added in the Spring '16 release.

Example of how you can use Quiddity and Callout Time to identify Apex classes
If the cause was a high db time, you can filter your ApexExecution file based on the QUIDDITY (E, H, M, R, V, W, X, L, K, or I) plus where RUN_TIME>5000.

The values for quiddity in the logs include:

A - Legacy Batch Apex
C - Schedule Apex
E - Inbound Email Service
F - Future
H - Apex REST
I - Invocable Action
K - Quick Action
L - Aura
M - Remote Action
Q - Queuable
R - Synchronous
S - Serial Batch Apex
T - Apex Tests
TS - Synchronous Apex Tests
TA - Asynchronous Apex Tests
V - Visualforce
W - SOAP Webservices
X - Execute Anonymous

This won't exactly tell you where you did hit the limit, but it will at least identify which synchronous Apex classes run longer than five seconds and probably should be optimized using the tips provided John's blog post.

In addition to quiddity, we also added EXEC_TIME to ApexTrigger files in order to get the run time of each trigger execution instead of RUN_TIME which turns out not to store any values in production. Who knew?!