Cut your Rails boot times on Heroku in half with a single command

dbackeus

David Backeus

Posted on March 23, 2022

Cut your Rails boot times on Heroku in half with a single command

TLDR;

heroku labs:enable build-in-app-dir -a <APP_NAME>

Now enjoy your Rails app booting ~twice as fast after your next deploy 🙌

But why?

One of the tradeoffs with majestic monoliths is that the larger they grow, the more code has to be loaded and interpreted at boot time. In massive code-bases, such as Shopify's and Github's, booting can take more than a minute (see eg. Upgrading Github to Ruby 2.7).

Particularly requiring files (eg. require "foo") tends to become a bottleneck due to Ruby having to iterate through all possible load paths to lookup matching files. This gets time consuming when it’s applied to thousands of files.

To alleviate this problem, the engineers at Shopify created bootsnap, a gem which automatically detects and caches exact load paths to make those require calls fast (see Bootsnap: Optimizing Ruby App Boot Time for details).

The bootsnap gem has been a default Rails gem since version 5.2 which was released back in 2018 and has been improving boot times in most environments ever since. But what about on Heroku?

Bootsnap on Heroku

As it turns out due to a quirk in how Heroku's Ruby buildpack initially builds the application in a /tmp folder before moving the results over to /app, the cache generated by bootsnap gets invalidated and can't be used at all. But after enabling the build-in-app-dir labs feature the entire build process takes place inside of /app which allows bootsnap to work as intended.

The feature is enabled via the heroku CLI tool:
heroku labs:enable build-in-app-dir -a <APP_NAME>

At Mynewsdesk this reduced the boot times of our 17 year old Rails codebase from ~16 seconds to ~8 seconds. The improvement is particularly noticeable when booting one off dynos via eg. heroku console or heroku run rails db:migrate.

There is a Github issue on this topic in the heroku-ruby-buildpack repo with some success stories in the comment section and a hint that build-in-app-dir may become the default behaviour in the future.

So far there have been no reports of issues after enabling this feature but you might want to try this on your staging environments first before enabling it in production to be sure. If any issues do turn up, don't forget to share your experience in the Github issue.

This is the first post in a planned series of tips and tricks for using Heroku efficiently. Feel free to follow me here on dev.to or @dbackeus on Twitter to get notified when new posts are published.

💖 💪 🙅 🚩
dbackeus
David Backeus

Posted on March 23, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related