Cleaning Up Residual Session Records

Problem

You want to clean up stale session records periodically.

Solution

Whether you've specified PStore or Active Record (i.e., filesystem or database) to store your application's session records, you need to clean up old sessions to avoid performance problems or running out of storage space.

For PStore session storage, the following find command removes all session files from /tmp that are older than two days:

$ find /tmp/ruby_sess.* -ctime +2 -print | xargs rm -rf

To run this command regularly, include it in a shell script, such as:

/home/rob/bin/clean-rails-sessions.sh:

#!/bin/sh find /tmp/ruby_sess.* -ctime +2 -print | xargs rm -rf

and have your system's cron facility run the script periodically. To have cron run the script run every 10 minutes, type crontab -e and add the following entry to your cron table:

# minute hour dom mon dow command
*/10 * * * * /home/rob/bin/clean-rails-sessions.sh

If you're storing sessions in your database via Active Record, you can create a small helper class and then call a method it defines to delete session records older than a specified amount of time. For example, add the following code to the bottom of your environment.rb file:

config/environment.rb:

...
class SessionCleanup
 def self.nuke_old_db_sessions
 CGI::Session::ActiveRecordStore::Session.destroy_all( 
 ['updated_at < ?', 20.minutes.ago] 
 ) 
 end 
end 

Then call the nuke_old_db_sessions method using your application's script/runner utility. Clean up your old session entries with a cron entry like this:

# minute hour dom mon dow command
*/10 * * * * ruby /var/www/cookbook/script/runner \ 
 script/runner -e production SessionCleanup.nuke_old_db_sessions

Discussion

Any Rails application that maintains state using sessions will accumulate stale session records over time. At some point, the stale sessions will become a problem by affecting performance or by filling up the available storage space.

You can set the session timeout for your application by adding the following line to environment.rb:

config/environment.rb:

ActionController::Base.session_options[:session_expires] = \
 20.minutes.from_now

This setting tries to ensure that sessions time out after 20 minutes but won't remove session records. Forcefully expiring user sessions by removing the stored session records kills two birds with one stone and helps prevent against malicious users who may have hijacked a user session.

See Also