Search

Thursday, April 21, 2011

CRM Web Services Performance Tweaks

Found a post regarding the CRM Web Services performance tweaks:
"The results are based on a test that involved performing 250 Account create operations in a single-threaded clean CRM environment.

Test Results

Raw Dog
15402.1472

PreAuthenticate
14450.7792

PreAuthenticate & Unsafe
12638.1728

Just Unsafe
9633.8528

Unsafe + IIS Tweaks
8862.744

So what does all this mean? The answers are below. For simplicity of the code samples, I assume you have already declared and setup a CrmService, the credentials are set and the URL is configured. I also assume there is a CRM Account called "acc" that is ready to go. Something like this:

CrmService crm = new CrmService();
crm.Credentials = System.Net.CredentialCache.DefaultCredentials;
crm.Url = http://localhost/MSCRMServices/2006/CrmService.asmx;

account acc = new account();
acc.name = "Test";

"Raw Dog" - This is the most straightforward and basic way of calling the CRM service, the code looks something like this:

crm.Create(acc);


PreAuthenticate - This is the first optimization that people seem to use and it does indeed provide a small benefit (~7%) over the default settings. The code looks like this:

crm.PreAuthenticate = true;
crm.Create(acc);

So why does this work? Reading the documentation suggests that this simply saves a round-trip required by NTLM's challenge-response authentication system. MSDN: "With the exception of the first request, the PreAuthenticate property indicates whether to send authentication information with subsequent requests without waiting to be challenged by the server. When PreAuthenticate is false, the WebRequest waits for an authentication challenge before sending authentication information." - Of course since most systems have "Keep Alives" enabled and my scenario is using the same connection over and over, the savings are minimal.


PreAuthenticate & Unsafe - This attempt adds the "UnsafeAuthenticatedConnectionSharing" option to the mix and we get yet another boost in performance (~12% over our last test and ~18% for our first test). The code looks like this:

crm.PreAuthenticate = true;
crm.UnsafeAuthenticatedConnectionSharing = true;
crm.Create(acc);

So why does this help? When used in conjunction with "Keep Alives" this option keeps an authenticated connection open to the server. MSDN: "The default value for this property is false, which causes the current connection to be closed after a request is completed. Your application must go through the authentication sequence every time it issues a new request. If this property is set to true, the connection used to retrieve the response remains open after the authentication has been performed. In this case, other requests that have this property set to true may use the connection without re-authenticating. In other words, if a connection has been authenticated for user A, user B may reuse A's connection; user B's request is fulfilled based on the credentials of user A."

This option is very powerful and before using it be sure to read up on it here. Since the connection is authenticated and shared, you need to make sure that two different users don't come in on the same connection. If they do, the server will think the user is the first user that opened the connection and allow the 2nd user to do whatever the 1st user could and to do it as if they were the same person. There is a way around this using the property "ConnectionGroupName" property. For my scenario of a bulk import, the only user that will be using this connection is the migration user and it will be the same user from start to end, so we are ok.


Unsafe - Now something curious happens when we keep PreAuthenticate off, but leave UnsafeAuthenticatedConnectionSharing on. This is where things get a bit odd, this is faster than have both options on; a full 38% faster than the original test as a matter of fact! The code looks like this:

crm.UnsafeAuthenticatedConnectionSharing = true;
crm.Create(acc);

Why does this work? Well the answer is I don't know and I have talked to people on the CRM team and the .NET team and nobody has a really good answer. The good new is that it does, perhaps it is best to leave it at that.


Tweaks - Finally, if you follow all the recommended steps for configuring a high-performance ASP.NET application (disable logging, enable ISAPI caching, make sure ASP.Net is tweaked) you can get a final little nip of performance. Basically do what this article says and we get another 9% bump in performance.



Be warned that not all settings are "safe" to use in all scenarios... please read up on the suggestions prior to implementing them in a production system."

No comments:

Post a Comment