SessionState Performance


 


Problem:


Unable to make the session state request to the session state server.
Please ensure that the ASP.NET State service is started and that the client and server ports are the same.
If the server is on a remote machine, please ensure that it accepts remote requests by checking the value of HKLM\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection.


 


Cause:


Excessive use of SessionState


 


Resolution:


Minor tweaks can be made, but be aware. You are pushing SessionState to it's absolute limits.



Scenario:


Judging from the number of calls we get it seems quite common for people to store all sorts of things in SessionState and to rely quite heavily on it. I would personally say that the rule of thumb is to avoid SessionState as much as possible.


 


The different ways of storing SessionState


You're probably already familiar with the three different ways of storing SessionState, but I'll recap them quickly, just to refresh your memory:




  • InProc

    In process. Works fine if you have only one web server. Great performance, but if the application pool recycles, then your SessionData is lost forever.

  • State Server

    The simple out-of process solution. By using the ASP.NET State Server you can share data between web servers. The ASP.NET State Server can be run either on one of the web servers or on a separate server.

  • SQL Server

    Using SQL server isn't that different from using the State Server. SQL Server may be a tiny bit slower performance-wise, but the main benefit is that you can set up a fail-over cluster.

 


Common myths


There are some common misunderstandings regarding SessionState and it's uses. The ones I come across most frequently would probably be the following:


Myth:

"SessionState is really efficient. If you store all datasets, etc. in a SessionVariable it's like having the data in RAM, rather than on disk"

Fact:

When storing session data out of process it is serialized, stored and deserialized. This is a CPU- and memory consuming process and if you store large objects in SessionState you will use a lot of resources to handle the data. For small chunks of data I'd recommend cookies, hidden controls (ViewState) or even query strings. For larger objects... Well, do you really need them for every single request?

 


 


Myth:

"The Server will only retrieve SessionState when I actually read or write to it."

Fact:

Sorry, but that's incorrect as well. The data will be deserialized and serialized with each request unless you have clearly specified otherwise.

 


 


Myth:

"It doesn't matter what type of data I store in SessionState."

Fact:

It does matter, and it matters a lot. For example; a 40KB string and a 40KB multi-dimensional array are not equivalent. The data must be serialized and deserialized, and serializing a string is a lot less CPU-consuming than serializing a complex array.

 


 


What is serialization anyway?


Serialization means transforming an object to a stream of bytes. This stream of bytes can then be sent over the web, saved to disk, etc. and be recreated on demand. When serializing the worker process takes your complex object and transform it to a simple byte stream that is easily dealt with. This byte stream in itself is pretty useless until you deserialize it. You can not access its properties until you've "unpacked it". Think of it as a .cab archive or instant coffee. 🙂


 


Increasing performance


If you are aware from the start that SessionState isn't the most effective way to store data, then you should be fine. If you're stuck with the ungrateful task of cleaning up someone else's mess, then you have a little more work to do.


 


The planning phase


Like I said, you should always try to limit your use of SessionState. It's quite common to store data "for later use", but unless you absolutely need it right now, then why store it in Session State? And if you absolutely need it right now, then why not use ViewState, cookies or some other means of temporary storage like a database? Here are some samples:


 



  • If you have a huge dataset that was really taxing to get, then save it to a temporary table or take it as a hint to rethink your database design.
  • Form data should be kept in ViewState or possibly in cookies.
  • Try really, really hard to keep Objects out of SessionState. Especially STA COM objects. If you really have to save an STA COM object, then remember to set the AspCompat attribute of the @ Page directive.
  • Disable Session State on all pages that don't require it, and set it to read-only on pages that don't require write-access. This is done with <@ Page EnableSessionState="..."> (Framework 2.0)
  • Read the article Improving .NET Application Performance and Scalability. Especially Chapter 6 which deals with ASP.NET.

Existing applications


There are a few things worth tryng if you're running an application and suddenly find yourself with a StateServer on it's knees begging for mercy. Please note that most of this is to be considered respiratory only. A few more users and you'll probably be facing the same scenario again. So my personal suggestion would probably be to quickly get the server up and running within acceptable parameters and then immediately begin working on a redesign. Anyway. here are my quick tips for a quick fix:



More than one StateServer:


If all else fails you can actually have more than one StateServer, provided that you have a webfarm. If you set up your load balancer to use sticky sessions you could actually run each web server with its own StateServer. This would mean that each web server would have its own settings for SessionState. This gives you many options for load balancing. If you, for example, have 8 web servers you could divide the servers into pairs and let each pair share an out of process StateServer. This would give you a solution with 8 web server and 4 state servers. You could even have a separate fail-over cluster for each web server. But as much as this would please your hardware vendor you're probably compensating for poor planning by adding horsepower.


Well I guess that's all for now.


/ Johan

Comments (12)

  1. dhruvin_g@hotmail.com says:

    i would like to comment here that SQL Server Session Storage is no slower than State Server. In most of the heavy traffic scenario it is the only thing that wins and comes really closer to the In Process State storage.

  2. JohanSt says:

    Thank you for the feedback.

    It is my general experience (as well as the documented one) that SQL is slightly slower, but it was really interesting to hear that your experience was different.

    Did you take any measures on the SQL server to optimize performance or was it quicker "out of the box"?

    Regards / Johan

  3. pmackay@hotmail.com says:

    I have to say that I lived the issue described in http://support.microsoft.com/?kbid=896600 personally.

    Also, we applied that hotfix before it came a public hotfix. Those days were tough.

    Patrick.

  4. pmackay@hotmail.com says:

    Ohh, btw, nice post…. I liked the myths. I guess that do you have more, don’t you?

    Patrick.

  5. Michael says:

    I am curious how much of this information would apply to server side caching.  Is there any similar performance issues to consider with caching DataSets?

  6. JohanSt says:

    Hi Michael,

    Session state is deserialized with every request (unless you set EnableSessionState="false"). Cached items are only retreived when you call Cache("Item"), so in that aspect they’re not as taxing as session state.

    Anyway; for a dataset you might want to look at the SqlCacheDependency Class instead…?

  7. Problem: When using Visual Studio 2005 to debug a web application under IIS7 you will find that after

  8. molinchung says:

    I will like to know whether ASP.NET 1.1, 2.0, and 3.5 web applications can share the same ASP.NET state service (aspnet_state).

  9. JohanSt says:

    Yes. There is only one version of the ASP.NET state service installed and it is shared by all framework versions.

    / Johan

  10. è©±éĄŒăźć°ć‘çŸŽć„ˆć­ă‚čトăƒȘăƒƒăƒ—ă‚’éš ă—æ’źă‚ŠïŒć…„ćż”ăȘăƒœăƒ‡ă‚Łăƒă‚§ăƒƒă‚Żă‚’ă™ă‚ŠæŠœă‘ăŠè¶…ć°ćž‹ă‚«ăƒĄăƒ©ă§æ’źćœ±ă—ăŸç„žć‹•ç”»ăŒă‚ąăƒƒăƒ—äž­ïŒæœŸé–“é™ćźšé…äżĄăźèĄæ’ƒçš„æ˜ ćƒă‚’èŠ‹é€ƒă™ăȘ

  11. Moin says:

    aspnet_regiis -i

    running this in the command prompt worked for me

  12. BlueSky2010 says:

    Loving reading your articles Johan – keep up your good work!

Skip to main content