ASP.NET Session State: Architectural and Performance Considerations

ASP.NET Session State: Architectural and Performance Considerations

  • Comments 11

I recently came across a great post on one of the internal forums describing the strengths and weaknesses of different ASP.NET session state strategies. Its author, J.D. Meier, has graciously given me permission to use it as the basis of a blog entry.

As you're probably aware, state management is an important consideration for web developers. The HTTP protocol is connectionless, so any web application that persists data across multiple web page requests needs some mechanism to ensure this session-based data is maintained. Examples of session-based data include shopping carts (on an ecommerce site), the currently logged-on user credentials, and other application-specific data that would normally be held on a client. Various strategies have been utilised over the last few years, including hidden forms, cookies and server-based state engines. Of these choices, the latter is perhaps architecturally most attractive since it reduces the dependence on a client; unfortunately, maintaining session state on the server can be expensive on resources and makes it hard to scale out using web farms or secure pages with HTTPS.

Enter the ASP.NET session state engine, which attempts to make server-side session state a much more viable option. ASP.NET offers three separate choices for session state storage when it's switched on: locally on the server (InProc), remotely in a SQL Server database (SqlServer), or remotely using a session state service (StateServer). I'll go through each of those options and compare the benefits of each.

InProc

The local option is not dissimilar to that provided by ASP, in that it requires all requests to come to the same physical server rather than being randomly split across multiple IIS machines. The upside is that it's very fast (it runs in-process), and it's simple to implement. If you've just got one web server, this is the best choice in most scenarios. The only time when you might want to consider something else in this scenario is when the session data is expensive to rebuild, since any InProc session data is flushed when the ASP.NET worker process or IIS restarts. If, for example, you're maintaining a shopping cart as local session data that gets cleared out, you risk annoying customers sufficiently that they take their business elsewhere.

For multiple servers, InProc is unsuitable unless you can implement some form of server affinity, so that every time a particular client requests a web page they are directed back to that same server. Services such as Network Load Balancing (part of Windows Server 2003 Enterprise Edition) can provide this, although they inevitably add their own overhead.

StateServer

I've come across a few developers who haven't come across this choice. The state server relies on a Windows service which is disabled by default, which perhaps explains why people haven't noticed it - go to Administrative Tools / Services and enable the ASP.NET State Service to get it working. You can run the state service on a dedicated machine or shared with a web server host; the main requirement to make this service work efficiently is plenty of RAM. Because the service is isolated from IIS, you can restart IIS without losing the session data contained within it, and you can point multiple distributed ASP.NET boxes at the same service, thereby removing server affinity issues. However, the session data isn't persisted onto disk, so it can't be backed up and a server reboot will lose the data. On the plus side, you don't need SQL Server or anything beyond a Windows licence to run it, making this option easy to set up and maintain. This option is however signficantly slower than using InProc, due to network latency and roundtrip costs. Keeping the state server on a dedicated private LAN with the other web server boxes will help.

Finally, don't forget that you can run the ASP.NET State Service in a single web server environment - this provides durability against IIS restarts, but at a performance cost due to it running out of process.

SqlServer

This is the high-end option in terms of flexibility and reliability, but is also the most expensive to build and maintain. Rather than storing session data in memory, it is persisted to a SQL Server instance. It's more reliable than any of the other approaches, since the data is persisted in a more durable form (e.g. it will survive a server restart and can be backed up). You can even use SQL Server clustering support to increase session state reliability still further. From a performance point of view, it's generally comparable to the StateServer service when you've got multiple web servers using it for session state. The session state itself is stored as a BLOB in a persisted or temporary table, which can reduce the serialization cost but makes it harder to view the session data itself.

In most cases, integrated Windows authentication is the best choice, preferably utilising Kerberos (NTLM requires an extra roundtrip for authentication). Connection pooling can be used to minimise the initial performance hit.

Further Reading

The MSDN documentation is quite good at describing the configuration of these options; meanwhile, Rob Howard has a short white paper that is now a little old but still mostly appropriate. Finally, keep an eye out for a new guide that will shortly be released from the Patterns & Practices group, entitled "Improving .NET Application Performance and Scalability". This paper will go into these topics and others in far greater detail.

  • Something that developers need to also pay close attention to is SerializableAttribute. When running InProc, any CLR type can be shoved into the session object without much consideration and be confident of retrieval in a subsequent page request. However, developers often find themselves with serialization problems when migrating a system to production where one of the two out of process modes is selected. This is because types that are to be stored in the HttpSessionState object must be marked with the SerializableAttribute when a setting other than InProc is used (since they will need to be marshalled between processes) e.g. : [Serializable] class Dog { } A good recommendation is for developers to assume that deployment will be an out of process mode of operation. Developers should use StateServer IMHO, that way, they will catch serialization problems at development time and not at deployment time.
  • Great comment Steve - very insightful.
  • Just to save you some headaches: Regarding important Steve's tip on marking classes [Serializable], there are several classes on the Framework Class Library that are NOT marked as serializable, and if you use objects of those types on your own objects, they will NOT be serializable, even if you tag them so. I had a most disapointing experience using a DataRow member on my classes, and then trying to put the session state on an State Server... ASp.NET said that "System.Xml.XmlBoundElement in Assembly System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is not marked as serializable". It's a (internal & undocumented) part of a DataRow object, and that has stoped me from changing the session state storage of my web app.
  • Well ... GB ... I have an object graph of my own objects that are serializable and they have a member that is a DataTable (which one would think includes DataRow instances). Maybe the DataTable creates the datarows on deserialization, meaning that having a DataRow as a member of a custom class is your whole problem.
  • It seems to me that introducting a State Server into a distributed web farm creates a single point-of-failure that does not fail gracefully. What is the best way to ensure that out-of-process session state management is "fault tolerant"?
  • Steve is 100% correct. I just got bit on this because I had a reference type passed into Session that was being read by one page (to display status) and being updated on another thread via an async call. Worked like a champ InProc. Won't work at all with SQLServer or StateServer Session storage.

    I will always assume out-of-proc from now on.
  • I have also experienced the same problem when i wrote a code that did not have classes marked as Serializable. My suggestion would be that InProc should not be used during the development of application as it saves the overhead of extra effort needed for changing the classes.Although StateServer(or for that matter SQL Server) are slower than InProc, they are the best viable options available when you think of scaling up your application.
  • Microsoft's out-of-proc technology for state management is only usable either for primitive applications or utilizing self-created state management server (code yourself). In my application I had to maintain complex COM object hierarcies that anayway would never persist in either SQL server or State Server.
    Moreover - because I am doing AJAX and my server gets bombarded by virtually 10s of requests per minute /per client - could you imagine how it would have sucked had I used state server (forgetting about COM objs inability to marshall).
    What kind of app is it? Very much like Google maps + tons of business logic on top (balloons, routing state etc...). Because of in-proc instability , i would probably end-up writing my own state server (in Delphi or C++)  that would efficiently
    hold these structures in RAM (including map-tiles cache), and use ASP.NET only as a presentation layer - there , i will use Session to store int IDs only.
  • I am so [url=http://access.2surf.eu]lucky[/url] on having what I have! And good luck in yours [url=http://2access.2surf.eu]search[/url].
    Just visit [url=http://access.122mb.com]my site[/url].









  • Hay guys. During testing of system that I'v develop (Business application for call center) I observed, that some times, session state server return null (in c# language) when asking, but should return a value (not a simple tape like .net DataSet).

    No matter, why it do that. The frequency of that behavior increase according to ammount of request/response cycle (in each cycle appliaction puts some data into session and gets some data back) and also to user making requests. Please help if you can explain that kind of behavior.

  • העשרה שבועית בנושא והפעם מאמר מקיף על האפשרויות של sessionState בתוך web.config. (נושא שנתתי הסבר מזורז

Page 1 of 1 (11 items)