Upgrading Rails 5 & 6 to Rails 8
Staying on an old Rails version feels safe, but it quietly piles up risk: missing security patches, a shrinking pool of developers who want to work on it, and features you simply can’t use. The good news is that upgrading is a well-trodden path — as long as you do it one major version at a time and lean on the tooling Rails gives you. Here’s a practical route from Rails 5/6 all the way to Rails 8.
Why bother upgrading?
Security:Only the latest few releases get patches. An unpatched app is a liability.Hiring:Strong developers want to work on a modern stack, not babysit a 2018 codebase.Cost & speed:Newer Rails and Ruby are faster and cheaper to run, and unlock features like Hotwire and the Solid trifecta.
The golden rule: one version at a time
The single biggest mistake is jumping from 5 straight to 8. Each major version has its own deprecations and removals; skipping them turns a series of small, debuggable changes into one giant, cascading mess. Walk the path: 5.2 → 6.0 → 6.1 → 7.0 → 7.1 → 7.2 → 8.0.
Step 1: Lock in a test baseline
You can’t upgrade safely without a green test suite. Run it first and note what passes — that’s your safety net for every step that follows.
bundle exec rspec # or: bin/rails test
If coverage is thin, invest here before touching anything. Tests are what tell you an upgrade broke something.
Step 2: Upgrade Ruby first
Each Rails version requires a minimum Ruby. Bump Ruby on its own, get the suite green, and deploy that — so you’re only changing one thing at a time.
# .ruby-version
3.3.6
Step 3: Bump one Rails version
Point the Gemfile at the next version and update just Rails and its dependencies:
# Gemfile
gem "rails", "~> 6.1.0"
bundle update rails
Then run the interactive updater, which walks you through framework default and config changes:
bin/rails app:update
Review every diff it proposes — especially files in config/initializers and config/environments.
Step 4: Adopt new defaults gradually
Rails gates new behaviour behind config.load_defaults. After upgrading, keep the old defaults until the app is stable, then raise them deliberately:
# config/application.rb
config.load_defaults 6.1
The generated config/initializers/new_framework_defaults_*.rb file lets you flip individual settings on one at a time instead of all at once.
Step 5: Audit your gems
A blocked dependency can derail the whole project. Before each jump, check that your gems support the target version:
bundle outdated
Read the changelogs for anything major. Replace abandoned gems early — discovering a dead gem halfway through is the classic mid-upgrade trap.
Step 6: Fix deprecations and validate
Run the suite again, fix what broke, and watch the logs for deprecation warnings — those are next version’s removals. Repeat steps 3–6 for each version until you reach 8.0, deploying after each successful jump.
Five traps to avoid
Jumping multiple majors at once— the fastest way to a mess.Upgrading with weak tests— you’ll ship regressions blind.Skipping the dependency audit— a dead gem can block you for days.Flipping all new defaults immediately— raiseload_defaultsonly once stable.Treating it as pure tech debt— frame it as the business investment it is, and protect dedicated time for it.
Wrapping up
A Rails upgrade isn’t a heroic rewrite — it’s a disciplined loop: bump one version, run app:update, audit gems, fix deprecations, get green, deploy, repeat. Do that, and you’ll land on Rails 8 with its Solid Queue, Solid Cache, and Kamal goodies, on a codebase that’s secure, fast, and a pleasure to hire for.