Controlling Rails Process Size

Eric Hodel | Wed, 13 Sep 2006 07:44:00 GMT

Posted in ,

Now that Ruby 1.8.5 is out setting process limits is easier than ever before! We used to use a small shell script run from cron to kill processes that got too big for their britches. Unfortunately this was difficult to do both well and simply (we chose simply).

Now, in Ruby 1.8.5, we have Process::setrlimit:

$ ri Process::setrlimit
----------------------------------------------------- Process::setrlimit
     Process.setrlimit(resource, cur_limit, max_limit)        => nil
     Process.setrlimit(resource, cur_limit)                   => nil
------------------------------------------------------------------------
     Sets the resource limit of the process. cur_limit means current 
     (soft) limit and max_limit means maximum (hard) limit.

     If max_limit is not given, cur_limit is used.

     resource indicates the kind of resource to limit. The list of 
     resources are OS dependent. Ruby may support following resources.

Process::RLIMIT_COREcore size (bytes) (SUSv3)
[...]
Process::RLIMIT_RSSresident memory size (bytes) (4.2BSD, GNU/Linux)

There's a bunch more in there, but those were the two I was most interested in using. I really don't want cores, and I don't want my application processes to grow too big, but I want cron jobs to get as big as they need to get.

At the top of config/environment.rb above everything else I have:

Process.setrlimit Process::RLIMIT_RSS, 1024*1024*150, Process::RLIM_INFINITY

And to eliminate core dumps, in config/environments/production.rb I have:

Process.setrlimit Process::RLIMIT_CORE, 0, Process::RLIM_INFINITY

Keeping the hard limit at infinity allows me to increase the limit at a later date, for example when running cron jobs. To give cron jobs different limits I've added a config/environments/cron.rb that slurps the production values then overrides as necessary:

eval File.read("#{RAILS_ROOT}/config/environments/production.rb")

CachedModel.use_local_cache = false

# Cron jobs can use a much memory as they want.
Process.setrlimit Process::RLIMIT_RSS, Process::RLIM_INFINITY

(That eval is in there because of that's the same hack that Rails::Initializer uses to expose config in environment files, bleh.) 1 comment

Comments RSS FEED

For people using Ruby 1.8.4 or earlier, you can use the proc-wait3 package (available on the RAA) to get the same functionality (and the same API).

Daniel Berger said 8 days later

Comments are disabled