Performance implications of querying entities in CRM 2013

When using the SDK to build applications that interact with Microsoft Dynamics CRM, a developer is presented with a host of options.  Early-bound vs. late bound…  Query expressions vs. LINQ…  I imagine that most developers will be like me in that some combination of the options will fit their personal style best.  What concerned me, however, was if there was a particular combination that performed better or worse than others.  When it comes down to it, better performance usually wins out over coding style.  So, I thought I would take some time and try to benchmark the performance of the various options.

Late vs. Early binding

With late binding, we interact with entities as a base type (Entity).  The Entity class has named properties for Id and LogicalName, and an array of the entity’s remaining Attributes.  An advantage of this method is a smaller payload during serialization, which can translate to better performance over the network.  Disadvantages primarily stem from the use of string keys to describe the attributes — developers run the risk of spelling errors with hard-coded attribute names, and refactoring is made more difficult.  Also, because the attributes are <string, object> pairs, types must be specified explicitly.  So, to access the Annual Revenue value of the Account entity, I might write code that looks like this:

With early binding, the CrmSvcUtil tool is used to create strongly-typed entity classes.  These entities, which derive from Entity, will contain all of the entity’s properties, attributes and relationships, providing the developer with compile-time checking of type references and the all-important IntelliSense support that we all know and love.  One disadvantage of this approach is that the entities must be regenerated to take advantage of changes to the CRM schema — this can be especially time consuming during initial CRM implementation as the schema is likely changing constantly.  Also, there is serialization to consider, as the additional type information in the entities will make their network payload larger.  But, an advantage is cleaner code and compile-time type checking.

Query expressions vs. LINQ

Query expressions provide a very CRM-specific way to retrieve entities, while LINQ syntax is more accessible across a broader audience.  LINQ CRM queries actually use query expressions under the covers, so overall the two will perform pretty much the same.  One thing to note is that a LINQ query, even for a single entity queried by its Id, will execute a RetrieveMultiple request instead of a Retrieve.
Additionally, both query types can be used with either early- or late-bound types.  So, all of the following are possible.

Great, but what about the performance?

I built a test harness that connected to an Online CRM 2013 instance that has a couple hundred accounts in it, and executed each of these queries for all accounts.  I then captured min/max/average execution time in seconds for each query type.  Here are the results:

I ran the tests several times, and while I will never claim to be a statistician these numbers (particularly the averages) appear to be pretty insignificant in their variance.  That tells me that, all else being equal, any of these methods should perform pretty much the same.

I ran similar tests for retrieving multiple entities in a single query (the code isn’t particularly interesting, so I won’t include it here), and the results look a lot like the others.


I like LINQ — it lets me use the same syntax for CRM queries that I would use with Entity Framework.  Also, as the queries get more complex, I feel that LINQ syntax is easier to read.  I like early-bound types — IntelliSense is my friend, and if I regenerate my entity classes I get more immediate feedback about refactoring.

But that’s just me.  If you prefer late-bound types and Query expressions, the good news is that your queries should perform the same as mine.

Also, I realize that these findings are based on a pretty simple set of operations.  I will be writing a follow-up post that covers more complicated operations like returning related entities & joins, and doing create/update/delete actions.