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 rake2. 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 43. 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
How to Cache Composer Dependencies in CICache Composer dependencies in GitHub Actions so PHP installs stop re-downloading packages. Cache the Compose…
How to Cache Dependencies in GitHub Actions (Every Ecosystem)Cache dependencies in GitHub Actions with actions/cache - correct keys and paths for npm, yarn, pnpm, pip, Ma…
How to Avoid Re-Downloading Dependencies in CIStop CI from re-downloading the same dependencies every run. Cache package stores, pin lockfiles, use offline…
How to Cache the Maven .m2 Repository in CICache the Maven ~/.m2/repository in GitHub Actions so JVM builds stop re-downloading JARs every run. Use the…