TL;DR: don’t run bundle exec before rails command, rails already checks the presence of Bundler through the Gemfile and sets up everything according to it without the overhead of bundle exec. rails command is the only exception to the rule. Additionally I’ve added a patch to Bundler that avoids calling Bundler.setup which adds unnecessary overhead.
I was researching on a huge Bundler 1.1 performance regression, @masterkain was hitting when running bundle exec rails runner ’’ (you shouldn’t run bundle exec before the rails command, but keep reading for now). I started to profile it using ruby-prof and one of the things I realized was that Bundler.setup (which is a considerable slow method because it calls Bundler::Runtime#setup) was ran 3 times. My first reaction was WTF?? 3 times??. I will write about my other findings in another blog post.
After analyzing the code, I found out that the first call to Bundle.setup is in Bundler::CLI#exec right before shelling out to run rails runner ’’. The second call is on boot.rb as part of the boot process (well actually it’s required from bundle exec through this rubyopt and on boot.rb the require returns false because it’s already required). And the last call starts on config/application.rb which ends up calling Bundler.require to finally call Bundler.setup for the third time. The second and third calls are run on the same process so Bundler.setup caches the result in @setup so there’s no slow down between those 2 calls. But the command passed to bundle exec runs in a different process (remember I said before that we were shelling out to run rails runner ’’) so the resulting execution of the first Bundler.setup won’t be available to the “rails runner process” and doesn’t make any sense. All that bundle exec needs to do is to setup the rubyopts needed to run the command you are passing to bundle exec. I’ve patched Bundler to do the right thing.
So don’t run bundle exec before rails command, this command is already aware of Bundler and sets up everything according to what you have on your Gemfile. If you prepend bundle exec before rails command all you will be adding is overhead of opening another process from Bundler and executing useless code since rails already does the right thing.
You probably already know about that, but I’ve seen a lot of proficient Rails developers doing it.
Read more about the topic in Yehuda’s blog



I run bundle exec rails since I don’t have the rails gem installed outside of my bundle. It is therefore not possible to “forget” bundle exec and run the wrong version of rails. I see your point however, but this is locally so performance is not a big issue.
What Nils said. I try to avoid having any gems at all on my system that aren’t installed by bundler, and every other binary installed by bundler requires to be invoked with “bundle exec”. Given that users all have to learn (or should learn) to run “bundle exec” for every other script, the case for making the rails script do magic to avoid it is pretty weak, and when it comes with a threefold performance drop, is practically non-existent.
I’d vote to dumb down the rails script – Principle of Least Surprise, and all that. Magic is for Christmas, not for programming.
I’m inclined to agree with Daniel. If the sole purpose of the rails command being “bundler aware” is to avoid having to run `bundle exec rails` then this will ultimately just lead to confusion. “Use bundle exec… unless you’re running the `rails` command.”
As I understand it, your patch eliminates the performance penalty. Assuming the patch is included with Bundler 1.1 final (currently at rc6), is there any OTHER reason not to run `bundle exec rails`? In the abscence of one, it seems like this post should have said ”`bundle exec rails` is about to get much faster” rather than “don’t run `bundle exec rails`.”
@Nils, @Daniel bundle exec is fine when rails command is not in the load path or was just installed by Bundler.
@Daniel Derek kind of agree with you guys. But from another point of view I don’t like to run bundle exec before every command, I think Bundler and Rubygems should integrate better and you shouldn’t have to prepend bundle exec every time.
@Derek The reason to avoid bundle exec when running rails command is because it doesn’t add anything, you don’t need it, just that (if the rails version you’re using is available outside Bundler).
Santiago,
If I’m understanding your last comment to both Nils and Daniel, if the rails command in not in the load path and is only in the bundle, then there is no performance hit for running bundle exec rails?
Also, does your patch remove the performance hit regardless of if rails is installed both outside and inside the bundle?
@Carlos if rails command is in the bundle there is a performance hit too but there’s nothing you can do. In order for it to work you have to do bundle exec rails …
Yes to the second question it makes bundle exec faster in general
I always emailed this website post page to all my contacts, since if like to read it afterward my friends will too.