Revamping Session State

I'm making a number of modifications to the site to support some new features, and in the process I wanted to revamp the state management architecture.

In a single server environment, using in-process session management is often a convenient and good way to maintain state. In fact, it's often the best way, but like everything else it depends on the user and technical requirements. ASP.NET offers out of process session management (see the "stateserver" option in the web.config), and also offers SQL Server session management for larger applications. Both of these options require all session objects to be serializable and come at a performance hit, so this may be problematic if you're relied heavily on in-process session management and the convenience of boxing and unboxing objects.

None of these options were particularly viable for me, and here's why: the in-process management is convenient, but state is lost when the application restarts. One of the brutal realities of using Webhost4Life is that this will happen very frequently. While I could use SQL Server, I'm not impressed with Webhost4Life's SQL Server performance. It's fine for general usage, but the last thing I want is to rely on it for session management.

From an architectural point of view, I wanted my state to be independent of the application, which means creating a state handler. That way, if I decided to change the implementation details later, it would be easy to do so without having to change any web code. This is a good design decision anyway -- even using in-process session management. I also wanted this to be serializable, which required some modifications to my custom objects.

What I ended up implementing was pretty cool (if I do say so) -- I ended up disabling session state altogether, gaining a nice performance boost in doing so. The state handler will serialize itself as XML, encrypt the entire XML document (using an SHA/128 bit key with configurable salt generation), and store it in a session cookie.

I ran a few benchmarks to test the performance, and it's quite favorable. The big plus is that state is maintained by the StateHandler and cookie, not by IIS. This method is reasonably secure -- cookie tampering, while the probability is not zero, is highly unlikely. (Not like the data is _that_ sensitive anyway, but it's always good to be aware of all issues).

Below are some benchmarks. In all cases disk I/O, RAM, and CPU utilization was reasonably equivalent. At best, these are rough benchmarks because the dev box was running IIS, the out-of-process state service, and SQL Server. In a realistic environment, the latter two would likely be on other servers.

Requests per minute:
In process: 17,862
Out of process: 16,394 (-8%)
SQL Server: 15,528 (-13%)
Sessionless w/ cookie encryption: 17,270 (-3%)
Sessionless w/o cookie encryption: 18,626 (+4%)

I think this is a really great solution if you need distributed session management, or require stable persistence (session will be maintained even if IIS recycles). From a performance standpoint, the out-of-process and SQL Server implementation benchmarks are inflated and, again, in a real life situation, I'd expect to see these numbers take a dive. It's cost effective, too -- the infrastructure overhead requirements to support a distributed state server would be expensive, as they are critical points of failure.

What are the downsides?
1) Requires session cookies. This is trivial since blocking first-party session cookies is very rare. The out of process and SQL Server state management options do offer cookieless modes, passing identifier information in the querystring.
2) Requires serializable objects. Note than anything other than in-process state management requires this, anyway.
3) Overhead and storage space. The cookie will add to the bandwidth requirements by passing more data to and from the client, depending on the size of the serialized state. The cookie will max out at 4k, so if you have a lot of data, this may be a limiting factor. Though, 4k is a lot per session...
4) Potentially more of a security risk. Essentially, each user is acting a distributed database. Even though the data is encrypted (which is way more than what some sites will do) the potential for injection or tampering is increased.
Comments are closed

My Apps

Dark Skies Astrophotography Journal Vol 1 Explore The Moon
Mars Explorer Moons of Jupiter Messier Object Explorer
Brew Finder Earthquake Explorer Venus Explorer  

My Worldmap

Month List