Bootsnap

> Beta version

Bootsnap is a library that overrides Kernel#require, Kernel#load, Module#autoload and in the case that ActiveSupport is used, it will also override a number of ActiveSupport methods.

Bootsnap creates 2 kinds of caches, a stable, long lived cache out of Ruby and Gem directories. These are assumed to never change and so we can cache more aggresively. Application code is expected to change frequently, so it is cached with little aggression (short lived bursts that should last only as long as the app takes to boot). This is the “volatile” cache.

Below is a diagram explaining how the overrides work.

Flowchart explaining Bootsnap

In this diagram, you might notice that we refer to cache and autoload_path_cache as the main points of override.

How it works

Caching paths is the main function of bootsnap. There are 2 types of caches:

  • Stable: For Gems and Rubies since these are highly unlikely to change
  • Volatile: For everything else, like your app code, since this is likely to change

This path is shown in the flowchart below. In a number of instances, scan is mentioned.

How path searching works

Usage

Add bootsnap to your Gemfile:

gem 'bootsnap'

Next, add this to your boot setup after require 'bundler/setup' but before the end.

require 'bootsnap'
Bootsnap.setup(
  cache_dir:            'tmp/cache',                      ## Path to your cache
  development_mode:     ENV['MY_ENV'] == 'development',
  load_path_cache:      true,                             ## Should we optimize the LOAD_PATH with a cache?
  autoload_paths_cache: true,                             ## Should we optimize the AUTOLOAD_PATH with a cache?
  disable_trace:        false,                            ## Sets `RubyVM::InstructionSequence.compile_option = { trace_instruction: false }`
  compile_cache_iseq:   true,                             ## Should compile Ruby code into iSeq cache?
  compile_cache_yaml:   true                              ## Should compile YAML into a cache?
)

Protip: You can replace require 'bootsnap' with BootLib::Require.from_gem('bootsnap', 'bootsnap') using this trick. This will help optimize boot time.