ASP.NET Session size limitation - c#

Is there some kind of Session size limitation or advisable value to not to surpass ?
In my web application I create a few DataTables to store user selections which are stored in session until user approves selections so I add those values to database.
The problem is that I don't know whether session is reliable enough to keep few objects in or not ?
Thanks!
more info
Session size is about 10-20KB max.

Here's a few notes about Session state:
InProc (mode="InProc") session state is limited to the amount of memory available to the worker process. Only object references are stored, not the objects themselves.
Out of process state management serialises objects before persisting them:
Out of Process state management using the session state server (mode="StateServer") is limited to the amount of memory available to the state service.
Out of Process state management using SQL Server (mode="SQLServer") is bound only by the maximum size of the SQL image data type or the maximum permitted size of the database.
Obviously there still has to be enough memory available to the worker process to be able to pull an out of session object back into memory and re-hydrate for the duration of the http request.
As I mentioned previously, out of process state management serialises objects before persisting them.
This means that objects must be serialisable which excludes, for example, XmlDocument or anything that inherits from MarshalByRef.
Attempting to serialise objects of this sort will result in the following exception:
Unable to serialize the session state. In 'StateServer' and
'SQLServer' mode, ASP.NET will serialize the session state objects,
and as a result non-serializable objects or MarshalByRef objects are
not permitted. The same restriction applies if similar serialization
is done by the custom session state store in 'Custom' mode.

Yes, it is reliable enough. It just isn't very scalable, so plan ahead. This will totally grind to a halt when you run it on more than 1 server.
And there is sort of a limit: Number-of-concurrent-Users * SizeOf-Session < Available-Mem
It depends of course on the size of the tables, storing a few kB is usually acceptable (although high traffic sites will try to keep it smaller).
If your users can share tables, then you can place that data in the Application object, a great saving.
And a session object is limited to the TimeOut setting, default is 20 min. One way to optimize memory consumption is reducing that, but that is a trade off with user convenience.

I am assuming that you are having the session stored in "inProc" mode. In this mode, ASP.NET applications' session, cache etc are stored in the web server's RAM (via aspnet_wp.exe process). And .NET does not get to use all of it. There is a setting in machine.config which tells the threshold limit (by default 60%). Once this threshold is reached, IIS will recycle the worker process, and all the session information is lost.
Note that, if your server hosts more than one asp.net application, the 60% of memory is to be shared by all apps. So if the cumulative memory usage reaches the threshold the worker process still gets recycled.
Alternative to this, besides optimizing your application to use session sparingly,is to set the application to use session in out of process mode (using a stateserver or sqlserver to store session information).
Out of process mode can bring down your system performance.
Refer to this article for more information on Session State Management.

You should always assume session is a very valuable storage and very limited. The consumption should be as little as possible, because you can never know how many users the application is going to support.
DataTable can be too large to store in sessions, unless it can be kept small enough.

Related

What can destroy a session object asp .net?

I work with Session[""] objects in ASP .NET/C# MVC. I do a lot of checking on them, but I ask myself, what can destroy a session object without I specify it ?
I want to be sure that these Session[""] will be intact during some processes and can be only cleared by my instructions or if the user quit the application.
If you're using InProc, then a number of things can kill a sessions state. e.g.
Timeout (this can be set in config)
AppPool recycle
Web.Config change
Server crash
If you need a more durable solution, have a read of this article, and there's a few alternatives in this article too.
It's dependent on the type of session state you use.
InProc - sessions are destroyed if the web server process shuts down or crashes. The default shutdown time is 20 minutes after the IIS Application Pool is in active. If the IIS Application pool hits its memory limits it will also shutdown, so this is the least recommended approach for session state management.
StateServer - sessions are stored in a separate service on a server. The session will stay active until this service shuts down or is unavailable. It's more reliable than InProc, but if the service shuts down you loose any session data.
SQLServer - sessions are stored in a SQL database. This is the most robust solution and sessions are essentially guaranteed until you destroy them, but it's also the most complex to set up, requiring SQL server and a database.
Custom - Some other method of storing sessions that you would have to specify.
More information on the subject can be found in the links below.
http://msdn.microsoft.com/en-us/library/vstudio/ms178581%28v=vs.100%29.aspx
http://msdn.microsoft.com/en-us/library/vstudio/system.web.sessionstate.sessionstatemode%28v=vs.100%29.aspx

How should I maintain the cart to avoid frequent trips to the server?

My project in MVC is an order carting project.
The carting is done with the following structure.
There is an order object which holds:
cOrder -> List<cOrderItem>
cOrderItem-> List<dressing>, List<topping>, List<specialInst>
I am holding it in Session. Is it the right approach to hold it in Session without losing performance. Or should I follow an alternate approach?
I presume what you mean by "trips to the server" you really mean "trips to the DB" because whenever are dealing with the Session you are at the server anyway.
The Session will do the job, however, there are a couple of caveats that might be a problem
Session is not persistent, it's all stored in memory. This means that there is the potential for you to lose the session at any point e.g. app pool recycle.
Given it's not persistent, this means that a users cart is only maintained within a single session i.e. if the users session expires they will effectively lose their cart.
One approach which I have used in the past is to use a client-side cookie to maintain a basket session, this means
It's persistent storage so it's retained across sessions (not just a single session)
Nothing is stored on the server
It's very quick
There are a couple of small caveats with this approach as well
Browsers need to have cookies enabled
Users can clear their cookies (as such, losing their basket)
However, I've found that these issues are very rarely a problem as most people enable cookies in their browser and most users very rarely clear their cookies (and the chances of them doing it during a session is relatively low).
Yes and no. :)
Placing stuff that needs to survive across requests in the server session is fine for smaller websites, but it does limit scaling; it will be more difficult to distribute the load over multiple server machines, because either the session would need to be replicated to each machine, or all requests from a particular user would need to be routed to the same machine. There are out-of-the-box solutions for this however, it is not that big a deal.
But holding stuff in the session has other downsides. The session timeout for example will kill all the products that were in the cart if the user decides to for for lunch in the middle of his shopping spree.
Ideally, these days, I would be looking at storing the cart locally, in localStorage. Support for this is increasing rapidly. You would have some big advantages over storing it in the session:
Less memory needed on the server(s).
More scalable as there is no server state; each request may be
routed to any server that has capacity at that moment.
No session timeouts killing your shopping cart.
Local code (Javascript) can access the shopping cart without having
to make trips to the server and back.
Option 4 is becoming more important as of late. If you have your data available locally there are many things you can do with it later on that would be more difficult otherwise. Working offline for example could be done that way. You can fill your cart offline and only need to be connected to actually place the order with the webshop.

Session State Server vs Custom Session State Provider

I have been tasked to scale out the session for an application. From my research the most obvious choice is to use the State Server session provider, because I don't need the users sessions to persist (SQL Server Session provider)
About the app:
Currently using InProc session provider
All objects stored in session are serializable
All objects are small (mostly simple objects (int, string) and a few simple class instances)
Before I dive head-first into the IT side of things and with the ability to provide a custom session provider with ASP.NET 4, should I even consider a custom session state provider. Why or why not? Are there any "good" ones out there?
Thanks!
User feedback:
Why are we using session: persistence of data between postbacks (e.g. user selections)
How: user makes a selection, selection is stored. User leaves a page and returns,
selections are restored. etc. etc.
Will be creating a web farm
I've provided some links you can read up on on properly scaling session using the state server.
Useful links from Maarten Balliauw's blog:
http://blog.maartenballiauw.be/post/2007/11/ASPNET-load-balancing-and-ASPNET-state-server-%28aspnet_state%29.aspx
http://blog.maartenballiauw.be/post/2008/01/ASPNET-Session-State-Partitioning.aspx
http://blog.maartenballiauw.be/post/2008/01/ASPNET-Session-State-Partitioning-using-State-Server-Load-Balancing.aspx
My State Server related projects:
http://www.codeproject.com/KB/aspnet/p2pstateserver.aspx (latest code at https://github.com/tenor/p2pStateServer)
http://www.codeproject.com/KB/aspnet/stateserverfailover.aspx
Hope that helps.
It depends on what you mean by "scaling" session storage. If your simply talking about session state performance, your not going to beat the in-process session state provider. Switching to the State Server provider will actually make things slower -- due to the extra overhead of serializing and transferring objects across process boundaries.
Where the State Server can help you scale, is that it allows multiple machines in a load balanced web-farm to share a single session state. It is limited by machine memory, however, and if you will have lots of concurrent sessions you may want to use the SQL Session State provider.
For the most performance in a web farm, you can also try using AppFabric as was previously suggested. I haven't done it myself but it is explained here.
Also, here's a link for using Memcached as a Session State provider. Again, I haven't used it, so I can't offer an opinion on it...
EDIT: As #HOCA mentions in the comments, there are 3rd party solutions if cost isn't an issue. One I've heard of (but not used) is ScaleOut SessionServer.
I would highly recommend that before you look in to scaling out session that you first evaluate whether session was even needed in the first place.
Session variables are serialized and deserialized for every single page load whether the page uses that data or not. (EDIT: Craig pointed out that you have some level of control over this in .net 4 http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstatebehavior.aspx However, this still has drawbacks, see comments to this answer.)
For single server instances this is okay as you are just pulling it from the local memory of your web server. The load on these apps tend to be pretty small so caching user specific information locally makes sense.
However, as soon as you move storage of session to another server you have increased the network requirements and page load times of your application. Namely, every page will result in the session data to be moved from the remote server, across the network wire, and into memory of the web server.
At this point you have to ask yourself: is the load to pull this information from the database server directly as necessary more than pulling it from the session server every single time?
There are few instances where pulling it from the database server as needed takes longer or results in more traffic than grabbing it from a remote session server.
Bearing in mind that a lot of people set up their database server(s) to also be session servers and you start to see why use of session doesn't make any sense.
The only time I would consider using session for load balanced web apps is if the time to acquire the data exceeded a "reasonable" amount of time. For example, if you have a really complex query to return a single value and this query would have to be run for lots of pages. But even then there are better ways that reduce the complexity of dealing with remote session data.
I would advise against the use of session state, regardless of the provider.
Especially with your "very small objects" use viewstate. Why?
Scales best of all. NOTHING to remember on the server.
NO worries about session timeout.
No worries about webfarms.
No worries about wasted resources for sessions that will never come back.
Especially in ASP.NET 4 viewstate can be very manageable and small.

Sessionstate not being saved between pages

i am having problems with an asp.net c# site whereby i am setting a session state object to true and then redirecting to another page that needs to check the value of the session state object and it is null.
Sometimes it is set correctly and other times is is simply null.
When i debug on my local machine it works perfectly every time. Only when i upload to my web server does this temperamental behaviour happen.
As it is based around the security of the site it is obviously important that the session data be valid and accurate every time.
Is session state data unreliable?
AFAIK its set to inproc, cookieless, 30 min timeout, vanilla installation of IIS.
Does anyone have any suggestions? Perhaps i need to thread.sleep inbetween the storing of the session data and the reading?
NB: the time between the write and the read is about 70ms.. ample time for the data to be written to RAM.....
No. It sounds like you are misusing session state. You can not rely on the user's session to be there. Your ASP.NET worker process could recycle, restarting the application and killing all sessions, or a file could change in your website, causing your application to restart and flushing all sessions, cookies could get flushed on the client, timeouts could happen, etc.
So you have to provide for all of these scenarios with Session State. Try to avoid using session state for things like this. If you're setting access inside your session state and you don't know exactly how it works, you could be opening your site up for a lot of security risks.
Everything point to a web farm. If you have different web servers on the production environment serving your application you would experiment this behavior.
I don't find any other explanation for this "WORKS ON MY MACHINE!"
I don't have an answer for your particular problem, but Claudio my be on to something.
What I have to say is that using session for security is so 90's. Literally.
FormsAuthentication was developed to replace that technique and does quite a fine job.
You should only rely upon session for trivial concerns that are easily recoverable.
Security is not one of those.
If the session state is lost, typically that's because your process either recycles or fails. I would never "rely" on the session state between pages. Instead you might want to try to persist data between pages some other way. Perhaps passing the information via form variables or saving the data in the database.
ASP.NET Profiles are a preferred way to save this sort of information. You might want to read ASP.NET State Management Recommendations.

Why is it a bad idea to use Session to store state in high traffic websites?

I am watching the ASP.NET learn videos on asp.net/learn. In this tutorial, they are building a quiz engine. At one point, the narrator explains that we are going to use the Session object to maintain the state between each page (each page contains a question and four answers). He says that "since this is a low traffic website" it is okay to use Session and that he doesn't have the time to implement a more sophisticated method.
I am just wondering what alternate method(s) is he hinting at? And why is session a bad choice for a high traffic website?
Storing data in a database, or in cookies or some other method that is not directly tying up web server memory.
In addition to load, session also raises issues with the ability to use farms since you would either need to synchronize the session across the farm, or make sessions sticky, which can impact scalability.
For alternatives you can read the article Nine Options for Managing Persistent User State in Your ASP.NET Application.
In the articles the author explains the pros and cons of each method.
From the summary:
ASP.NET provides many different ways
to persist data between user requests.
You can use the Application object,
cookies, hidden fields, the Session or
Cache objects, and lots of other
methods. Deciding when to use each of
these can sometimes be difficult. This
article will introduce the
aforementioned techniques and present
some guidelines on when to use them.
Although many of these techniques
existed in classic ASP, best practices
for when to use them have changed with
the introduction of the .NET
Framework. To persist data in ASP.NET,
you'll have to adjust what you learned
previously about handling state in
ASP.
Session data is stored in the RAM of the server, if you have a high traffic site that is going to get full real quick and the last thing you want is that data being swapped to disk.
As gaijin42 says, cookies or a DB are the alternative.
Session as a state storage method is rough in high traffic systems for several reasons.
First, the default Session storage method is in-process, meaning that if you have a load-balanced web farm, you'll constantly 'lose' Session information as a user gets pages served from different servers.
The in-proc Session server also dies when an app pool is recycled, which happens more often on higher traffic servers.
The scalability options for Session data are
Use the freely available ASP.NET
Session Server and point all your
applications at it
Use SQL Server to store Session data.
Due to the nature of Session data in general, neither of these is a very good option for a very high traffic site (unless you have unlimited money to throw at the hardware).
For high traffic websites you might be looking at Memcached. It is a caching mecanism that is stored on the RAM of a remote computer. Just recently a win32 port has been made of the library (was only possible with linux before).
I'm not going to repeat what was already mentioned here, but another alternative is using the Application hash. It should be used sparingly, since it will consume memory on your web server as Adam has already mentioned, but it does provide a good way to cache things that are common across ALL your users.
This keeps you from having to go back to your database to retrieve information that most likely was already asked for by someone else.
Another alternative similar to Application is Cache which has more flexibility in terms of when it gets released, duration, etc.
Here's some links in case you're interested:
ASP NET Caching Application State
We use a database for anything high traffic or that will result in large session state. Instead we store a pointer in the real sessionstate that points to our database record. Then the only overhead we have is the bandwidth between the web server and database server which will be much less than between any given user and the web server.

Categories

Resources