Ruby 3.0

3.0 released 25 December 2020, latest 3.0.7.

Ruby 3.0 reached end of life on 23 April 2024.

What changed

Ruby 3.0 completed the keyword-argument separation that Ruby 2.7 had warned about: a positional Hash is no longer implicitly converted into keyword arguments when calling methods. This can change calls to methods, delegation code, and wrapper APIs unless callers use ** or callees accept the intended form. The cycle added RBS type signatures and bundled tooling such as TypeProf, giving projects a standard way to describe Ruby APIs for static analysis and editor support. It also introduced experimental concurrency and scheduling primitives, notably Ractor for actor-style isolation and the Fiber scheduler interface for nonblocking I/O integration. Other language additions included endless method definitions, rightward assignment, and expanded pattern-matching support. These concurrency facilities were opt-in and experimental; upgrading to Ruby 3.0 did not automatically make an application concurrent or nonblocking.

What staying costs

Ruby 3.0 has reached end of life, so upstream no longer provides fixes for newly discovered security issues, interpreter defects, or compatibility problems in this line. The practical exposure is not limited to the Ruby executable: applications may become harder to build and deploy as operating-system images, OpenSSL and other system libraries, native gems, CI images, and hosting platforms move forward. Dependency maintainers increasingly set minimum Ruby versions above an end-of-life line, which can leave a team choosing between an unpatched runtime and frozen application dependencies. Remaining on 3.0 also preserves its completed keyword-argument behavior, so delayed upgrades can accumulate compatibility work in gems, framework integrations, and internal delegation helpers.

What to do

Plan a move to a currently supported Ruby line, selecting a target that is compatible with the application framework and its critical gems. First inventory every runtime location, including developer environments, CI jobs, containers, background workers, scheduled jobs, and native extensions. Update the Ruby version declaration, base images, and CI matrix, then regenerate or rebuild native gems in the target environment rather than reusing compiled artifacts. Run the full test suite with warnings enabled and specifically inspect method delegation, calls that pass Hash values, and code that forwards keyword arguments; make keyword intent explicit with ** where required. Verify production-only integrations such as database adapters, TLS clients, observability agents, job runners, and extension gems in a staging environment. Treat Ractor and Fiber scheduler adoption as separate design work, not as an upgrade requirement. Roll out with monitoring and a tested rollback path, while keeping dependencies within the compatibility range of the chosen supported Ruby line.

We can tell you what moving off Ruby 3.0 involves.

What it takes to move off Ruby 3.0 depends on what you built on it — the version you are on, how much depends on it, and how much of the work is mechanical. Leave your email with this version and we can tell you what that looks like for you.

Not sure yet? Get my plan