SharePoint is a popular choice for intranet applications and therefore it is important that it performs well to ensure employee productivity. Waiting ten seconds just to load the initial dashboard doesn’t necessarily support that. At a recent customer engagement we identified an interesting source of a potential performance problem that impacts ALL SharePoint and .NET-based installations that use the ServicePointManager to access web services. It turns out that ServicePointManager comes with a default setting that allows two concurrent connections. If you happen to have a SharePoint dashboard that queries data from more than two data sources, your end users will suffer from a very long page load time. In this blog I explain the steps that one of our customers took to identify and solve this particular problem. This issue has a broader impact beyond SharePoint; I suggest all .NET Developers to look into this issue.
Step 1: Identify Problematic Pages
The first question is: do we have a problem or not? You can either wait for your end users to start complain to the help desk or be proactive and look at end-user response times. The following screenshot shows data from each individual visitor who accessed a SharePoint application. Focusing on one visit that was identified as having a frustrating experience shows the individual visited pages. Starting with an extremely costly first page (43 seconds to load) the visitor also suffered from an extremely slow response time for the following two actions (click on Home and reloading Default.aspx):More than six seconds were spent only on server-side processing. There was also a very long wait at the Client (JS Time) for the initial page.
Step 2: Identify Problematic Web Parts
Drilling into the actual details of the Default.aspx page for that particular Visitor shows which Web Parts are involved in that Page as well as where these Web Parts spend most of their time:Web Parts such as the DataFormWebPart or ContentEditorWebPart spend most of their time waiting on resources
Looking at the details shows us that these Web Parts actually spawn multiple background threads to retrieve data from different backend web services and then they spend time waiting (sync) on those threads when they are done with their work. A closer look also reveals that each of these threads is taking a significant amount of time in I/O:The WebParts spawn multiple background threads. These threads are all performing I/O operations that take up a very long time (up to 5.8s)
Step 3: Identify Root Cause of Problem
Why are all of these background threads taking so much time? Expanding the internals of the first call shows that it takes 5.8 seconds until the web service actually sends a response back on the socket. So – that explains why the first asynchronous thread takes 5.8 seconds:First web service call takes 5.8s until we receive data on the socket that is used internally by the ServicePoint implementation.
The other web service calls executed by the remaining background threads pretty much go down through the same execution path spending most of their time waiting for an available outgoing connection:We have a total of 10 background threads that try to execute a web service call. Most of them spend their time waiting in the ServicePoint instead of sending the actual request.
Step 4: Fix The Problem
Doing a little research (aka use your favorite search engine) on this brings up the following post on stackoverflow.com: Max Number of concurrent connections which ultimately leads us to the MSDN documentation for ServicePointManager where we learn that the default setting for concurrent connections is two!The default of 2 concurrent connections causes parallel executing web service requests to wait until there is a free connection available.
So – the solution to this problem is to change the default value. In this case, it should be at least set to the number of allowed Web Parts on a single dashboard because most of them will execute asynchronous web service calls.
This problem is obviously not only relevant for custom SharePoint development but can impact any .NET application that uses ServicePointManager. It was a very interesting case with this customer as they only used out-of-the-box components provided by SharePoint and still ran into this problem. If you are implementing custom SharePoint solutions I also recommend checking out another blog series about the Top SharePoint Performance Problems when implementing your custom Web Parts and Web Controls starting with: How to Avoid the Top 5 SharePoint Performance Problems.