Fork me on GitHub

ASP.NET Concurrent Ajax Requests and Session State Blocking 11



Today I ran into a pretty interesting and puzzling issue while trying to load many different long running content areas on a screen asynchronously via Ajax & jQuery.

It appeared that if I shot off Ajax Request A, B, C, D… that they would always return one after the other (roughly). They never deviated from this pattern and were not appearing to be operating asynchronously from an ASP.NET perspective. To try to figure out what is going on here consider the following C# and JS code:

Example Code





Check out what (unexpectedly) happens in Firebug’s Net tab:


Firebug Behavior… What?

It appears that my Thread.Sleep of 10 seconds is causing each request to return one after the other (apparently ASP.NET is queuing them differently than Firebug did here in this example), but only after the previous request in the queue has completed. The 10 requests actually completed in almost exactly 100 seconds, as expected given this behavior.

Upon seeing this issue I was initially very confused and began to question my core  ASP.NET understanding such as: is ASP.NET blocking other requests simply because of this Sleep()? Shouldn’t ASP.NET be spinning up other threads to deal with the concurrent request load up to the configured limit?


An Answer, Straight from Microsoft

Luckily it turned out to be something I have never encountered (but I bet people will be seeing more of as the web goes Ajax) Session State blocking! Take a look at the Microsoft Session State article bottom of the page called Concurrent Requests and Session State, let me sum it up:

  • Only one request at a time may have Read/Write access to a particular session (as determined by session id cookie) at a time. R/W access is default
  • Any additional requests requiring ANY session access will be blocked until the previous R/W request has completed



Well then… it looks like when ASP.NET was written (over 10 years ago now right?) concurrent ASP.NET processed requests (as opposed to static files) almost never happened as Gmail didn’t make its big Ajax foray until 2005. I’m guessing this behavior exists because because you can get into some interesting situations when it comes to merging written session data keys across multiple possible concurrent requests. I think this might be worth revisiting now in 2011 and allowing for something like “last wins for the same session key”. There are other situations that could occur but I’d rather read some documentation about the expected behavior (with do’s and don’ts) rather than have this occur. Luckily there is a less elegant but workable solution for MVC for right now:


A Solution for MVC 3

Luckily Microsoft has provided ENUM values in System.Web.SessionState.SessionStateBehavior that allow us to give up rights to an exclusive session lock. Mainly the values:

  • ReadOnly – Doesn’t block other requests because this request can’t update session
  • Disabled – Can’t block, and your best option for performance in StateServer & SQL modes because no serialization needs to occur. Remember that all of session is serialized and de-serialized per user every time. Not just particular keys your are accessing.


Throw a new for MVC 3 attribute with your desired Enum value on your Controller class as such:



(It’s too bad you can’t do this at the action level. My initial thought is that is too late in the ASP.NET pipeline events once Action discovery occurs unfortunately)


Now take a look at our Firebug Net tab (that’s more like it! but what about that light brown bar…):


Browser Concurrent Request Blocking

Browsers limit the concurrent connections per server that can be used at a given time. I have read this is to be nice, to developers and server admins maybe? The brown bar in Firefox indicates a request that is being blocked until the connection frees up for another request. This can be changed by editing configuration entries but it’d be tough to ask for that on a publicly facing website!



Hopefully this helped you diagnose some odd Ajax performance issues! I know the solution isn’t really ideal if you wanted to update session. I find the more I develop web applications the less I use session in favor of using the DOM, jQuery Data, JSON etc, but that certainly doesn’t work for everything! I’m thinking I might explore the possibility of a “MergeSessionStateProvider” if the proper ASP.NET hooks are there to implement it. I think given where the web is going something like this might be becoming more and more critical for the best possible user experience.

Thanks for reading!

11 thoughts on “ASP.NET Concurrent Ajax Requests and Session State Blocking

  1. Reply Ramesh Sep 16, 2016 10:03 am

    Really great post. We got direction for the issue we have. Thanks.

  2. Pingback: Sitecore 8 Ajax Controller Blocking - Wesley Lomax

  3. Reply Tiling Jun 8, 2015 11:46 pm

    Hi there to every one, the contents present at this website are in fact remarkable for people experience,
    well, keep up the good work fellows.

  4. Reply Derrick Lewis May 29, 2015 12:13 pm

    Holy crap, I am so glad we found this post! We were having an issue where multiple ajax requests on a page were causing hundreds of connections to get stuck in the RequestAcquireState state, and we were pulling our hair out. We were down for almost a full 24 hours, and no amount of server updates or config changes seemed to help. We finally found this article, implemented the attribute on our controller, and it works PERFECTLY! You are an absolute life saver. If you are ever in Tuscaloosa, AL, I owe you a beer! Thanks a ton.


    • Reply John Culviner May 31, 2015 9:55 pm

      Glad it helped! Yeah nearly absurd that is the behavior! Most things these days I remove all the SessionProvider, Membership Provider etc. stuff and do it from scratch (there are much better ways to handle distributed session state these days with Redis etc) Works well in a pinch as long as you turn that part off for sure!

  5. Reply efaruk Dec 15, 2014 3:44 am

    Lock mechanism exist on both provider and session module (IIS Session Module). You can develop custom session module, but you still need provider without locking or You can develop custom provider without locking but you still need IIS session module and it is not so simple to implement at that level.

    The Solution is UnlockedStateProvider [aka Unlocked]

    Follow the white rabbit 😛 (Check the demo project, it explains everything.)

    • Reply John Culviner Dec 16, 2014 10:35 pm

      Awesome! Good to know someone has implemented this. More recently I’ve actually ended up disabling Session State and using distributed caches (or even just calling the DB for user info or whatever). Any state I want to have I generally get from the cache/db and then hydrate into UserContext object with DI scoped to a request. Thanks for the reply!

  6. Reply Satish Aug 8, 2013 11:28 pm

    Excellent post. The session state was what was blocking my MVC app from streaming results even though I was running periodic refreshes via jquery to get them. Once I set the SessionStateBehaviour to ReadOnly I could see a tremendous difference. Thank you very much.

  7. Reply Rich Mealey May 17, 2013 12:18 pm

    GREAT Summary! I wished I had read it before I spent far too much time troubleshooting. Still, thanks for confirming my findings.

  8. Reply Liangying Feb 5, 2013 1:41 am

    Great Thanks!!

  9. Reply Martin Jan 14, 2013 11:04 am

    Life saver, plan and simple…

Leave a Reply