Skip to content
Latchkey

How to Cache Bundler Gems in CI

bundle install recompiles native gem extensions on every cold runner. Caching the installed gems skips that compile entirely.

The expensive part of bundle install is building native extensions, not downloading. Cache the vendored gem path keyed on Gemfile.lock and CI reuses the compiled artifacts.

1. Let setup-ruby cache for you

ruby/setup-ruby with bundler-cache: true installs and caches gems keyed on Gemfile.lock automatically.

.github/workflows/ci.yml
- uses: ruby/setup-ruby@v1
  with:
    ruby-version: '3.3'
    bundler-cache: true
- run: bundle exec rake

2. Or cache vendor/bundle manually

If you need control, configure a vendored path and cache it.

.github/workflows/ci.yml
- run: bundle config set --local path vendor/bundle
- uses: actions/cache@v4
  with:
    path: vendor/bundle
    key: gems-${{ hashFiles('Gemfile.lock') }}
    restore-keys: gems-
- run: bundle install --jobs 4

3. Key on Gemfile.lock

The lock pins exact versions including platform. Keying on it means a dependency bump invalidates cleanly and a platform mismatch never restores the wrong native build.

Key takeaways

  • The cost is native extension compilation, not download, so cache the installed gems.
  • setup-ruby with bundler-cache: true is the least-effort option.
  • Key the cache on Gemfile.lock so version and platform changes invalidate correctly.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →