On Rails sessions

Like everything else in Rails, sessions are pretty easy to use. Unfortunately, the default session configuration isn’t particular well suited for a shared host.

You see, by default CGI::Session::PStore (the default session store in Rails) will use the operating system’s temp dir, which on nix-like systems means /tmp. Which is fine, the /tmp dir well suited for small, temporary files that will get cleaned out, which is also why the /tmp partition is traditionally being kept small (it’s actually quite big here at TextDrive compared to traditions).

But here’s the problem, Rails loves to create new session files, one particular case where you’ll end up with an abnormal number of “useless” sessions is RSS/Atom feeds. See, most feedreaders just request a new session every time they hit a feed, let’s say your users are nice and only refreshes their readers once every hour, that’s 24 new sessions per day per user. Let’s say you have a 100 users loyally refreshing their feeds every hour, every day; that’s 2400 new sessions. If you suddenly get popular and get a whooping 250 loyal visitors a day, then that’s 6000 new sessions. And that’s only for the feedreaders, your normal visitors will create a good amount of new sessions as well (even though browsers are a bit smarter about being able to “reuse” a previously created session, thanks to cookies).
Now all that activity will end up with a decent amount of session files, which is fine. The problem is that your site is hosted on a shared server, where you’ll have plenty of neighbors doing the same thing, and /tmp will quickly end up looking like this:


ls -l /tmp/ | grep -c ruby
79962

That’s eighty-thousand ruby sessions, let’s say all those users are nice and don’t keep anything big in their sessions, so they’re about four kilobytes each, that’s still about 320 megabytes worth of session files. Enough to fill up most /tmp partitions based on traditional partition schemes. And that is bad, since things like MySQL stores its socket file in there.

OK, enough 3rd grade mathematics. Luckily Rails has alternatives, CGI::Session::PStore allows you to set an alternative “tmpdir” by sending it the ‘tmpdir’ option key, within Rails you could do it like this, in your environment.rb:
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.update(:tmpdir => File.join(RAILS_ROOT, '/tmp'))
which would set it to /path/to/your/railsapp/tmp, very easy and unobtrusive to the real /tmp partition.

That’s one way, even better would be to use ActiveRecordStore to store the sessions in your database. Not only does it not involve files on the filesystem, it’ll also make your application faster. Just look and uncomment this line in your environment.rb:
config.action_controller.session_store = :active_record_store
and run rake create_sessions_table to create the sessions table.

Once upon a time Scott Barron wrote this little thing called Session Container Performance in Ruby on Rails, and if you look at the graphs you’ll see how performance is slowly degrading over time using the default PStore, while staying constant using ActiveRecordStore. Scott wrote that thing late 2004, so the numbers may or may not be the same, but the very same principles and conclusions still apply.

·:· Posted 23 January 2006, 10:11 by Johan Sørensen to Upon our Recommendation  |  

  1. “Uncomment” the ActiveRecordStore line not “comment out”.

    Also, remember to set your RAILS_ENV appropriately before running “rake create_sessions_table”. Oh, one other thing. The most recent Typo already uses ActiveRecordStore, so no need to do this if you are just running Typo.

    Sean    23 January 2006, 14:49    #
  2. Great point, Johan. I have moved my site to this.

    Sean – what is the easiest way to set your RAILS_ENV for rake?

    Can you please provide an example?

    michael    24 January 2006, 03:31    #
  3. Michael – rake environment RAILS_ENV=production create_sessions_table

    Sean    24 January 2006, 05:06    #
  4. Sean – thanks so much.

    That’ll make my life easier elsewhere.

    michael    24 January 2006, 11:55    #