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:
"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"
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?
"The Server will only retrieve SessionState when I actually read or write to it."
Sorry, but that's incorrect as well. The data will be deserialized and serialized with each request unless you have clearly specified otherwise.
"It doesn't matter what type of data I store in SessionState."
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.
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.
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:
- Disable Session State on all pages that don't use it, or set it to read-only by using the EnableSessionState attribute in the @ Page directive (Framework 2.0)
- If you've hit the ceiling and are running the in-process state server, then there might be some extra performance to be gained by setting up an out-of process State Server on a separate machine.
- If you're using the out of process StateServer, then you might want to increase the timeout according to the following article:
State server logs Event ID 1072 or Event ID 1076 - You might also want to increase the available number of ports on the StateServer by following the guidelines in this article: (I know it doesn't mention StateServer, but the solution is the same.)
PRB: "WSAEADDRESSINUSE" Error Message When You Try to Connect Through an Anonymous Port After You Increase the IMAP Connection Limit - There is also a possibility that this fix will help you out:
FIX: You may receive an error message when you use the ASP.NET State Server service to store ASP.NET session state in the .NET Framework 1.1
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
Anonymous
November 19, 2006
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.Anonymous
November 19, 2006
The comment has been removedAnonymous
February 27, 2007
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.Anonymous
February 27, 2007
Ohh, btw, nice post.... I liked the myths. I guess that do you have more, don't you? Patrick.Anonymous
April 13, 2007
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?Anonymous
April 15, 2007
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...?Anonymous
March 26, 2008
Problem: When using Visual Studio 2005 to debug a web application under IIS7 you will find that afterAnonymous
September 17, 2008
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).Anonymous
September 17, 2008
Yes. There is only one version of the ASP.NET state service installed and it is shared by all framework versions. / JohanAnonymous
June 13, 2009
話題の小向美奈子ストリップを隠し撮り!入念なボディチェックをすり抜けて超小型カメラで撮影した神動画がアップ中!期間限定配信の衝撃的映像を見逃すなAnonymous
October 20, 2009
aspnet_regiis -i running this in the command prompt worked for meAnonymous
April 17, 2014
Loving reading your articles Johan - keep up your good work!