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