Latest in branch 7.2
7.2.3.1
Released 23 Mar 2026
(2 months ago)
SoftwareRuby on Rails
Version7.2
Status
Supported
Initial release7.2.0
09 Aug 2024
(1 year ago)
Latest release7.2.3.1
23 Mar 2026
(2 months ago)
End of bug fixes09 Aug 2025
(Ended 9 months ago)
End of security fixes09 Aug 2026
(Ends in 2 months)
Release noteshttps://github.com/rails/rails/releases/tag/v7.2.3.1
Source codehttps://github.com/rails/rails/tree/v7.2.3.1
Downloadhttps://github.com/rails/rails/releases/tag/v7.2.3.1
Ruby on Rails 7.2 ReleasesView full list

What Is New in Ruby on Rails 7.2

Category Highlights
New Features Dev container support via rails new --devcontainer; default PWA manifest and service worker files; per-transaction commit/rollback callbacks; allow_browser version guard in ApplicationController; YJIT enabled by default on Ruby 3.3+; jemalloc in default Dockerfile; GitHub CI workflow and Brakeman for new apps; omakase RuboCop rules out of the box
Improvements Puma default thread count lowered from 5 to 3 for better latency; Active Job automatically defers enqueuing until after transaction commit; ActiveRecord.after_all_transactions_commit helper added; puma-dev setup suggested in bin/setup; system tests default to Headless Chrome
Breaking Changes Ruby 3.1 is now the minimum required version; dozens of previously deprecated APIs removed across Active Record, Active Support, Active Job, Action Pack, Action Mailer, and Railties; @rails/ujs removed in favor of Turbo; transaction block exit via return/break/throw no longer auto-rolls back
Deprecations allow_deprecated_singular_associations_name config deprecated; commit_transaction_on_non_local_return config deprecated; use_big_decimal_serializer in Active Job deprecated; allow_deprecated_parameters_hash_equality in Action Controller deprecated; passing content to void elements via tag builder deprecated

How Does Dev Container Support in Rails 7.2 Change Your Local Setup?

Rails 7.2 ships first-class dev container support, letting you spin up a fully reproducible development environment in Docker without configuring anything by hand. For new apps, pass the flag at generation time:

$ rails new myapp --devcontainer

For existing applications, run the generator directly:

$ rails devcontainer

The generated .devcontainer folder includes a Dockerfile, a docker-compose.yml, and a devcontainer.json wired for VS Code. Out of the box you get Redis (for Kredis and Action Cable), your chosen database, a Headless Chrome container for system tests, and Active Storage configured for local disk with preview features working.

In practice, this means onboarding a new engineer goes from "set up Postgres, Redis, Chrome, configure credentials..." to "open in Dev Container." Watch out for teams that already maintain custom Docker setups -- the generated config is a sensible starting point, not a mandatory migration.

How Do the New Active Record Transaction Callbacks Work in Rails 7.2?

Rails 7.2 introduces two closely related features that finally give you clean, reliable hooks tied to transaction lifecycle -- without having to reach for model callbacks or monkey-patch connection pools.

Per-transaction callbacks let you register after_commit (or rollback) blocks directly on the transaction object yielded by ActiveRecord::Base.transaction:

Article.transaction do |transaction|
  article.update(published: true)

  transaction.after_commit do
    PublishNotificationMailer.with(article: article).deliver_later
  end
end

You can also attach to the current transaction without a block using ActiveRecord::Base.current_transaction, and when code might run inside or outside a transaction, the new ActiveRecord.after_all_transactions_commit handles both cases gracefully:

def publish_article(article)
  article.update(published: true)

  ActiveRecord.after_all_transactions_commit do
    PublishNotificationMailer.with(article: article).deliver_later
  end
end

This matters most in service objects that send emails, enqueue jobs, or call external APIs after a write. Previously you had to litter code with after_commit model callbacks or accept subtle race conditions. Most teams will find after_all_transactions_commit is the idiom they have wanted for years.

Why Does Rails 7.2 Change the Default Puma Thread Count and Enable YJIT?

Rails 7.2 ships two complementary performance changes that reflect hard-won production experience: Puma's default thread count drops from 5 to 3, and YJIT is enabled automatically for apps running on Ruby 3.3 or newer.

Thread count: The conventional wisdom of "more threads = more concurrency" breaks down for well-optimized Rails apps where SQL queries are fast and slow work runs in background jobs. With 5 threads, Ruby spends significant time waiting for the Global VM Lock (GVL) to release, which hurts p99 latency. Dropping to 3 threads reduces GVL contention without meaningfully reducing throughput for typical workloads.

YJIT: Ruby's JIT compiler has matured to the point where the Rails team is confident enabling it by default. On Ruby 3.3+, expect 15-25% latency improvements with no code changes required. If your environment does not support YJIT or you need to opt out, set:

Rails.application.config.yjit = false

Watch out for memory-constrained environments -- YJIT increases resident memory usage. Pair it with the jemalloc integration that is now baked into the default Dockerfile to offset fragmentation costs. Most teams running on Ruby 3.3 in containers should see a meaningful improvement with no migration effort.

What Does the Job Enqueuing Within Transactions Fix Mean for Existing Rails Apps?

Rails 7.2 automatically defers Active Job enqueuing until after the wrapping transaction commits, eliminating one of the most common and painful race conditions in Rails applications.

The problem: enqueuing a job inside a transaction risks a worker picking it up and running before the transaction commits. The job reads stale or missing data, and subtle errors follow -- often silently.

Topic.transaction do
  topic = Topic.create

  # Before 7.2: job could run before topic is visible to other connections
  NewTopicNotificationJob.perform_later(topic)
end

In Rails 7.2, the enqueue is held until after commit. If the transaction rolls back, the job is dropped entirely. This is the correct default for the vast majority of applications.

If you have jobs that deliberately need to be enqueued regardless of transaction outcome -- for example, audit or compensating jobs -- you can opt out per-job:

class NewTopicNotificationJob < ApplicationJob
  self.enqueue_after_transaction_commit = :never
end

This matters if you are running Sidekiq, GoodJob, or any adapter that supports this behavior. Review any jobs currently enqueued inside transactions in your codebase -- in most cases you will remove workarounds you added to compensate for this exact bug.

What Tooling Ships by Default in New Rails 7.2 Applications?

Rails 7.2 opinionates new application generation significantly, bundling a complete modern development and CI toolkit out of the box.

  • RuboCop with rubocop-rails-omakase: Enforces the Rails team's preferred Ruby style. This is not meant to be the final word on style -- use it as a starting point and adapt it to your team's conventions.
  • Brakeman: Static security analysis runs automatically in the new GitHub CI workflow on every push. Common vulnerabilities like SQL injection, XSS, and mass assignment issues get flagged before reaching production.
  • GitHub CI workflow: New apps include a .github/workflows directory preconfigured for Dependabot, Brakeman, RuboCop, and running the full test suite.
  • PWA files: A default service worker and web app manifest are generated under app/views/pwa, mounted at the root via explicit routes. They render through ERB, so you can make them dynamic from day one.
  • Browser version guard: allow_browser versions: :modern is set in ApplicationController by default. Outdated browsers receive a 406 Not Acceptable response and are served public/406-unsupported-browser.html. Fine-grained control is available:
class ApplicationController < ActionController::Base
  allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
end

For teams inheriting existing apps, none of these are forced on you during upgrade -- they apply to newly generated apps only. Adopting them selectively is straightforward.

What Was Removed in Rails 7.2 That Could Break Your Upgrade?

Rails 7.2 completes the cleanup of APIs deprecated in 7.0 and 7.1. If you have been diligent about addressing deprecation warnings on your current stack, most of these will not surprise you. If not, run your test suite on Rails 7.1 first and clear all warnings before upgrading.

Key removals to audit for:

  • Active Record: ActiveRecord::Base.clear_active_connections!, flush_idle_connections!, and related pool management methods removed. Use the connection pool API directly.
  • Active Record: Singular association lookup by plural name is gone. Check your model associations if you relied on this shorthand.
  • Active Record: alias_attribute with a non-existent source attribute no longer silently succeeds -- it raises.
  • Active Record: Transaction block exit via return, break, or throw no longer automatically rolls back the transaction. This was a footgun; the removal is intentional, but it may change behavior in subtle ways.
  • Active Support: Calling deprecate, deprecate_constant, and related helpers without a deprecator argument is removed. Update any engine or gem code that calls these.
  • Action View: @rails/ujs is fully removed. If you have not migrated to Turbo, this is the forcing function.
  • Railties: Rails.application.secrets is removed. Use Rails credentials (rails credentials:edit) instead.
  • Railties: Oracle, SQL Server, and JRuby-specific DB adapters are removed from rails new and db:system:change commands.
  • Active Job: The :exponentially_longer symbol for retry_on wait: is removed. Replace it with an explicit lambda or proc.

Ruby 3.1 is now the minimum version. If you are on Ruby 2.x or 3.0, that is the first item to resolve before anything else.

Frequently Asked Questions about Ruby on Rails 7.2

Does upgrading to Rails 7.2 require Ruby 3.1 or higher?
Yes, Ruby 3.1 is the new minimum version required by Rails 7.2. Applications still running Ruby 2.x or 3.0 must upgrade Ruby before targeting Rails 7.2.

Will my existing jobs that enqueue inside transactions break after upgrading to Rails 7.2?
They will not break, but their behavior changes -- enqueuing is now deferred until after the transaction commits. Jobs that were previously enqueued immediately inside a transaction will now wait for commit, and will be dropped if the transaction rolls back. To restore the previous behavior for a specific job, set self.enqueue_after_transaction_commit = :never on that job class.

Is YJIT safe to enable in production after upgrading to Rails 7.2?
YJIT is enabled automatically only when running Ruby 3.3 or newer and is considered stable for production use. It typically delivers 15-25% latency improvements, though it increases memory usage. If your environment is memory-constrained, monitor RSS carefully and disable it via Rails.application.config.yjit = false if needed.

Do the new RuboCop and Brakeman defaults affect existing applications during upgrade?
No -- they are only added when generating new applications or plugins. Upgrading an existing app to Rails 7.2 does not automatically install RuboCop or Brakeman. You can adopt them separately by adding rubocop-rails-omakase and brakeman to your Gemfile and copying the configuration from a freshly generated app.

How does the allow_browser version guard work and can I customize it?
The allow_browser class method, added to ApplicationController in new Rails 7.2 apps, checks incoming User-Agent headers and serves a 406 response with public/406-unsupported-browser.html for browsers older than the specified versions. You can target specific browsers by passing a hash like allow_browser versions: { safari: 16.4, firefox: 121, ie: false }, and scope it to specific actions with only: or except: options. Agents not reporting a user-agent header are always allowed through.

What is the migration path away from Rails.application.secrets which was removed in 7.2?
Use Rails credentials instead, which are managed via rails credentials:edit and stored encrypted in config/credentials.yml.enc. Any values previously read from Rails.application.secrets should be moved to credentials or environment variables, and accessed via Rails.application.credentials.your_key or ENV.

Releases In Branch 7.2

VersionRelease date
7.2.3.123 Mar 2026
(2 months ago)
7.2.328 Oct 2025
(7 months ago)
7.2.2.213 Aug 2025
(9 months ago)
7.2.2.110 Dec 2024
(1 year ago)
7.2.230 Oct 2024
(1 year ago)
7.2.1.223 Oct 2024
(1 year ago)
7.2.1.115 Oct 2024
(1 year ago)
7.2.122 Aug 2024
(1 year ago)
7.2.009 Aug 2024
(1 year ago)
7.2.0.rc106 Aug 2024
(1 year ago)
7.2.0.beta311 Jul 2024
(1 year ago)
7.2.0.beta204 Jun 2024
(1 year ago)
7.2.0.beta129 May 2024
(2 years ago)