Improving ASP.NET Performance Part 11: Session State Management

In this article we’ll discuss Session State Management. If you need session state in ASP.NET, there are three session state modes that you can choose from. Each mode offers varying degrees of performance and scalability as described in the following list:





  • InProc. The in-process store provides the fastest access to session state. There are no serialization or marshaling costs involved because state is maintained within the managed memory of the ASP.NET process.  When the process recycles, the state data is lost, although you can disable process recycling in IIS 6 if process recycling affects your application. The in-process store limits application scalability because you cannot use it in conjunction with multiple worker processes; for example, it prevents Web farm or Web garden deployment. Also, high numbers of large or concurrent sessions can cause your application to run out of memory.
  • StateServer. The session state service, a Microsoft Win32® service, can be installed on your local Web server or on a remote server that is accessible by all Web servers in a Web farm. This approach scales well, but performance is reduced in comparison to the in-process provider because of the additional serialization and marshaling that is required to transfer the state to and from the state store.
  • SQL Server. Microsoft SQL Server provides a highly scalable and easily available solution. SQL Server is a solution that is well-suited to large amounts of session state. The serialization and marshalling costs are the same as the costs for the session state service, although overall performance is slightly lower. SQL Server provides clustering for failover, although this is not supported in the default configuration for session state. To enable clustering for failover, you have to apply configuration changes, and the session data must be stored in a non-temporary table.

Choosing a State Store


The in-process state store provides excellent performance and scales well. However, most high volume Web applications run in a Web farm. To be able to scale out, you need to choose between the session state service and the SQL Server state store. With either of these choices, you have to understand the associated impact of network latency and serialization, and you have to measure them to ensure that your application meets its performance objectives. Use the following information to help choose a state store:

  • Single Web server. Use the in-process state store when you have a single Web server, when you want optimum session state performance, and when you have a reasonable and limited number of concurrent sessions. Use the session state service running on the local Web server when your sessions are expensive to rebuild and when you require durability in the event of an ASP.NET restart. Use the SQL Server state store when reliability is your primary concern.
  • Web farm. Avoid the in-process option, and avoid running the session state service on the local Web server. These cause server affinity. You can use Internet Protocol (IP) affinity to ensure that the same server handles subsequent requests from the same client, but Internet service providers (ISP) that use a reverse proxy cause problems for this approach. Use a remote session state service or use SQL Server for Web farm scenarios.
  • StateServer versus SQLServer. Use a remote state service, if you do not have a SQL Server database. Use SQL Server for enterprise applications or high volume Web applications. If your remote state service and your Web server are separated by a firewall, then you need to open a port. The default port is port 42424. You can change the port in the following registry key:



Best Practices

To ensure optimized session state performance, follow the guidelines outlined in the following sections.

Prefer Basic Types to Reduce Serialization Costs

You incur serialization overhead if you use the StateServer or the SQLServer out-of-process state stores. The simpler the object graph, the faster it should serialize. To minimize serialization costs, use basic types such as Int, Byte, Decimal, String, DateTime, TimeSpan, Guid, IntPtr, and UintPrt. ASP.NET uses an optimized internal serialization method to serialize basic types. Complex types are serialized using a relatively slow BinaryFormatter object. For complex types, you can use the Serializable attribute, or you can implement the ISerializable interface. Using this interface provides you with more precise control and may speed up serialization.

Minimize what you serialize. Disable serialization when you do not use it, and mark specific fields from a serializable class that you want to exclude with the NonSerialized attribute. Alternatively, control the serialization process by using the ISerializable interface.

Only implement the ISerializable interface as a last resort. New formatters provided by newer versions of the .NET Framework and improvements to the framework provided serialization will not be utilized once you take this approach. Prefer the NonSerialized attribute.

Disable Session State If You Do Not Use It

If you do not use session state, disable session state to eliminate redundant session processing performed by ASP.NET. You might not use session state because you store simple state on the client and then pass it to the server for each request. You can disable session state for all applications on the server, for specific applications, or for individual pages, as described in the following list:


  • To disable session state for all applications on your server, use the following element in the Machine.config file. <sessionState mode=’Off’/>

You can also remove the session state module from <httpModules> to completely remove session processing overhead.

  • To disable session state for a specific application, use the following element in the Web.config file of the application.  <sessionState mode=’Off’/>
  • To disable session state for a specific Web page, use the following page setting. <%@ Page EnableSessionState=”false” . . .%>



Avoid Storing STA COM Objects in Session State

Storing STA COM objects in session state causes thread affinity. Thread affinity severely affects performance and scalability. If you do use STA COM objects in session state, be sure to set the AspCompat attribute of the @ Page directive.

Use the ReadOnly Attribute When You Can

Page requests that use session state internally use a ReaderWriterLock object to manage session data. This allows multiple reads to occur at the same time when no lock is held. When the writer acquires the lock to update session state, all read requests are blocked. Normally two calls are made to the database for each request. The first call connects to the database, marks the session as locked, and executes the page. The second call writes any changes and unlocks the session. For pages that only read session data, consider setting EnableSessionState to ReadOnly: <%@ Page EnableSessionState=”ReadOnly” . . .%>

Setting EnableSessionState to ReadOnly is particularly useful when you use frames. In this event, the default setting serializes the execution of the page because a ReaderWriterLock is used. By setting EnableSessionState to ReadOnly, you avoid blocking, and you send fewer calls to the database. One option is to disable sessions in the configuration file as shown earlier, and to set the ReadOnly attribute on a page-by-page basis.

In our next artice we’ll describe some of the best practices for View State Management.