Writing

Two Rails versions get security patches today. On 7 November, it's one.

September 8, 2026 · Amit Solanki

Here is the state of Rails support as I write this, taken from the official maintenance policy:

SeriesBug fixes untilSecurity fixes until
8.1.x10 October 202610 October 2027
8.0.x7 May 2026 (passed)7 November 2026
7.2.xpassed9 August 2026 (passed)

Read the bottom row again. Rails 7.2 stopped receiving security fixes on 9 August 2026. That was four weeks ago. Every Rails application on 7.2 or below - 7.1, 7.0, 6.x, 5.x, the 4.2 app somebody still runs on a box nobody wants to touch - is now outside the window entirely. Rails is blunt about what that means: “When a release series is no longer supported, it’s your own responsibility to deal with bugs and security issues.”

And on 7 November 2026, Rails 8.0 joins them. At that point exactly one series, 8.1, is inside the security window.

The second clock

The part that catches teams out is that there are two clocks, not one, and they run at different speeds. Bug-fix support lasts a year. Security support lasts two.

So Rails 8.0 stopped receiving bug fixes on 7 May 2026, four months ago, while still receiving security patches until November. A team running 8.0 today is in a state that feels supported and mostly isn’t: you will get a patch if someone finds a CVE, and you will get nothing at all if you hit a framework bug. “We’re on a supported version” is true and not very useful.

The same thing is about to happen one step up. Rails 8.1 drops out of bug-fix support on 10 October 2026, about a month from now. If 8.2 has shipped by then the picture resets, because the policy is a rolling window tied to releases rather than a fixed schedule, and the policy explicitly extends support for the previous release until the next one ships if a year goes by without a release. But as the published dates stand today, there is a stretch this autumn where the only series inside the security window is also outside the bug-fix window.

None of this is a crisis. It is a calendar, and the calendar is public. The problem is that almost nobody reads it until something forces them to, and by then the upgrade is urgent, which is the worst condition under which to do one.

The other calendar nobody checks

Ruby runs its own schedule, and it does not care about yours (the branch list is here):

RubyStatusEOL
4.0normal maintenance-
3.4normal maintenance-
3.3security maintenance31 March 2027 (expected)
3.2end of life1 April 2026
3.1end of life26 March 2025

Ruby 3.2 went end of life on 1 April 2026. Not security maintenance. End of life. If your .ruby-version says 3.2 or lower, the interpreter your production application runs on receives nothing at all, regardless of which Rails you are on.

This matters more than it looks, because the two upgrades are entangled. A Rails major version usually raises its minimum Ruby, so the Rails upgrade you were putting off often turns out to be a Ruby upgrade first, and the Ruby upgrade is the one that breaks native extensions and C-extension gems in ways that are tedious rather than difficult. Teams that budget for one and discover the other are the teams whose two-week upgrade becomes a two-month one.

Five minutes to find out where you actually are

cat .ruby-version                  # or check the Gemfile / .tool-versions
bundle list | grep -E ' rails '    # the real resolved version, not the Gemfile constraint
bundle outdated --strict           # everything with a newer release available

Then the question that actually predicts the difficulty, which is not the Rails version at all:

bundle list | wc -l                # how many gems are in the graph

I have been writing Rails since its 1.x days in 2007, which means I have done every one of these upgrades: 1 to 2, 2 to 3, 3 to 4, and on to 8. Twice in twenty years the framework itself was genuinely the problem.

Rails 2 to 3 broke everything. The Merb merge rewrote the framework underneath the application: new router, new mailer API, Bundler replacing config.gem, ActiveModel arriving, the old plugin architecture retired. It is the largest breaking change in the framework’s history and nothing since has come close. Even then, the framework was not what took the time. Rails documented what it had changed and shipped a guide, while the ecosystem spent months catching up around it. Every plugin had to be rewritten for the new architecture and a good number never were. You did not sit blocked on Rails. You sat blocked on a plugin whose author had moved on.

Rails 5 to 6 was the other one, and it broke differently. Zeitwerk replaced the classic autoloader, so what changed was how constants resolve, which put the breakage inside your own application’s file naming rather than in anyone else’s gems. Announced in advance, shipped with a compatibility mode, and still a real piece of work.

Two out of eight, both flagged ahead of time, both finite. The rest of the time Rails is, by the standards of large frameworks, unusually well documented and unusually well behaved: there is an official guide per version, the deprecation warnings are honest, and rails app:update does real work. The framework part is the predictable part.

What blocks upgrades is the dependency graph. It is the gem that was last released in 2021 and pins an old ActiveSupport. It is the fork of a fork someone made to fix a bug that has since been fixed upstream. It is the four gems that all depend on a fifth, unmaintained one. Nothing in bundle outdated tells you which of those are trivial and which are load-bearing, and the count above is a rough proxy for how long it will take to find out.

That is also why “we’ll just do the upgrade” estimates are wrong so consistently in one direction. The graph part is discovery work, and you cannot estimate discovery before you have done it.

What actually works

Three things, all of which are about sequencing rather than cleverness:

Read the graph before touching the code. Every gem, its current version, its latest version, whether it is still maintained, and what it constrains. The output is a list of decisions - upgrade, replace, vendor, remove - and most of those decisions can be made and shipped independently, before the Rails version changes at all.

Get the test suite honest first. Not comprehensive. Honest. A suite with twelve skipped specs and a flaky one everyone re-runs is worse than a small suite you trust, because during an upgrade the suite is the only instrument you have. Every hour spent making it truthful is repaid the first time it disagrees with you.

Ship it in pieces. The failure mode I would bet on, sight unseen, is the upgrade branch that lives for three months and drifts further from main every week. Dual-boot the two versions, move the graph forward in mergeable increments, and keep the branch measured in days. An upgrade that lands in twelve small deploys is not a slower upgrade than one big one. It is the only kind that reliably lands at all.

The reason I care about this shape rather than the specific gem versions is that I spent years keeping a large integration platform upgradeable while it was under constant production load, with 130+ production API integrations against systems whose owners had their own release schedules and no interest in mine. You learn quickly that the only changes that survive contact with a running business are the ones small enough to ship on a Tuesday and reverse on a Wednesday.

The dates, once more

  • 9 August 2026 - Rails 7.2 left the security window. Passed.
  • 10 October 2026 - Rails 8.1 leaves bug-fix support.
  • 7 November 2026 - Rails 8.0 leaves the security window.
  • 1 April 2026 - Ruby 3.2 reached end of life. Passed.

Two of those four have already happened and most teams running those versions have not noticed. The other two are inside the next nine weeks.

If you want a straight answer about where your application sits and what it would actually take to move it, that is a bounded piece of work rather than a conversation. I call it an Architecture Roadmap: a dependency and risk map, the three to five failure modes most likely to cause you a bad week, a sequenced plan where each step ships on its own, and a quote for every recommendation, line by line. $2,800, delivered within ten business days of getting access. No code changes, and no production access needed.

Tell me your Rails version and roughly how many gems are in your dependency graph - [email protected] or @amitkssolanki on GitHub. Those two numbers are usually enough for me to tell you whether this is a week or a quarter.

Working through something similar?

← All writing