Rails 3 Benchmarks Startup Time

March 14, 2011

I have been having an annoying problem recently. One of the projects I am working on has a fairly large Gemfile and this is impacting startup time considerably on Ruby 1.9.2.

Ruby Start-up Times is a good article detailing boot up times for different ruby versions with a relatively fresh app.

Well, the development app I am currently working on has 148 gems defined in the Gemfile.lock. I don’t think this is overly excessive as many gems such as devise have many dependencies.

The result is that it takes a long time to bootup rails when using 1.9.2. This means that repetitive tasks such as tests, generating migrations, running migrations, rake tasks, generators, basically anything which requires a boot of the rails environment takes a long time.

This impacts the speedy development feel which rails gives you, diminishing the experience somewhat. I decided to try and see different boot times for different ruby versions.

For the benchmarks I used the same script as used on the post Ruby Start-up Times

#!/bin/bash
  echo puts Time.now > test_script
  time rails runner test_script
  time rails runner test_script
  time rails runner test_script

Rails startup performance comparison

The graph above shows the average run time for the above script in seconds for each of the ruby versions listed. The ruby versions were installed using rvm. The most recent REE gave a mysql2 segmentation fault so I went with the earlier version.

Results

Rubinius is painfully slow to startup, for me it is currently unusable. 1.9.2 is significantly slower than 1.8.7 for bootup. This is highly frustrating as once the application starts up, 1.9.2 feels snappier than 1.8.7.

REE takes the title for the fastest rails 3 bootup time in development for a project with a number of gems defined in the Gemfile.

Possible reasons for 1.9.2’s terrible performance

There is a thread about this on Rails-Core

To quote Yehuda Katz

There are things that the C require code does in 1.9 that slow things down. One such example is re-checking $LOAD_PATH to make sure it is all expanded on every require. This is something that should be addressed by ruby-core. I’ll open a ticket on redmine if there isn’t one already.

I am also experiencing this problem and a $LOAD_PATH issue seems like a potential cause. Lets hope it gets fixed soon.

Digging deeper there is a bug report on the ruby bugtracker but unfortunately it looks to be scheduled for the 1.9.3 release. It doesnt look like this is going to be coming out any time soon, so another solution needs to be found.

Suggestions for a quick fix

  • It is possible to stop bundler requiring all the gems on startup, and you then need to manually require them in your code. This is a potential solution but it would be a lot better if the bug in 1.9.2 could be fixed instead.
  • Use REE for most of your development and use 1.9.2 in a separate terminal if you need it for tests etc.
  • Some other kind of lazy loading solution would be excellent, or even better someone with knowledge of ruby internals who can fix this problem and it be released as a patch release rather than waiting for 1.9.3.