๐ Living Document - Updated until Rails 8.1 stable release
Report Date: October 5, 2025
Current Version: Rails 8.0
Target Version: Rails 8.1 (Beta 1 Released September 2025)
Contributors: 500+ developers, 2,500+ commits
๐ Executive Summary
Rails 8.1 represents a significant evolution in the Rails framework,
introducing powerful new capabilities for job management, developer
productivity, mobile applications, and multi-tenancy. This release continues
Rails' mission to "compress the complexity of modern web apps" while
maintaining backward compatibility with Rails 8.0.
๐งช Local CI Integration
Run tests locally with CI config - 50-60% faster feedback, 15-25% CI
cost reduction
๐ฑ Native Mobile Framework
Hotwire Native + Turbo Offline for web & mobile
๐ฑ Action Push Native
Official iOS/Android push notifications (10M+/day at 37signals)
๐ Active Job Continuations
Resilient, resumable background jobs
๐ข Active Record Tenanting
First-class multi-tenancy support
๐ Structured Event Reporting
Enhanced observability and logging
๐ Major New Features
1. Active Job Continuations
Impact: High | Led by: Donal McBreen
(37signals)
Transform long-running jobs into resilient, resumable processes that can
survive deployments and restarts.
What it does:
Breaks jobs into discrete steps with defined checkpoints
Resumes execution from last completed step after interruption
Particularly valuable for Kamal deployments (30-second shutdown windows)
Uses cursor-based tracking for progress management
Example Use Case:
class DataMigrationJob < ApplicationJob
include ActiveJob::Continuations
def initialize(batch_size: 1000)
@batch_size = batch_size
end
def process
# Process records in batches
# Job automatically resumes from cursor position if interrupted
end
def finalize
# Cleanup and completion tasks
end
end
Business Value:
Zero-downtime deployments with long-running background tasks
Reduced job failure costs (no need to restart from beginning)
Better resource utilization during maintenance windows
2. Local CI Integration
Impact: High | Led by: Jeremy Daer
(37signals)
Run your complete test suite locally with the same configuration as CI/CD
environments.
What it does:
Provides default CI declaration DSL in config/ci.rb
Executed via bin/ci command
Significant performance improvements demonstrated
Consistent testing between local and CI environments
Benefits:
Catch issues before pushing to CI pipeline
Faster feedback loops for developers
Reduced CI costs from failed builds
Standardized test execution across team
Developer Experience:
$ bin/ci
# Runs full test suite with CI configuration
# Same environment, same results as GitHub Actions/CircleCI
3. Action Push Native (Mobile Push Notifications)
Impact: High | Official Rails Project
First-class support for sending push notifications to iOS and Android
devices.
Platforms Supported:
iOS: Apple Push Notification service (APNs)
Android: Firebase Cloud Messaging (FCM)
Setup:
bundle add action_push_native
bin/rails g action_push_native:install
bin/rails action_push_native:install:migrations
bin/rails db:migrate
Google: Firebase service account credentials (project_id, encryption_key)
Business Value:
Native mobile engagement capabilities
No third-party service dependencies
Cost reduction (direct APNs/FCM integration)
Consistent notification delivery across platforms
4. Active Record Tenanting
Impact: High | Multi-Tenant Architecture
Build multi-tenant applications while writing code as if it were
single-tenant.
What it does:
Automatic tenant isolation at the database level
Tenant resolver extracts tenant information from requests
Convention-based approach (minimal configuration)
Seamless integration with existing Active Record patterns
Architecture:
# Write code as single-tenant
class Post < ApplicationRecord
belongs_to :user
end
# Framework handles multi-tenancy automatically
# Each tenant sees only their data
Business Value:
Simplified SaaS application development
Data isolation and security by default
Reduced development complexity
Scalable multi-customer architecture
5. Structured Event Reporting
Impact: Medium | Led by: Adrianna Chang
(Shopify)
Unified interface for producing structured, machine-readable events.
What it does:
Complements existing ActiveSupport::Notifications
JSON-structured events optimized for post-processing
Event tagging and context management
Flexible subscriber system
Usage Examples:
# Emit structured events
Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
# Tag events for filtering
Rails.event.tagged("graphql") do
Rails.event.notify("user.signup", user_id: 123)
end
# Set global context
Rails.event.set_context(request_id: "abc123", shop_id: 456)
Business Value:
Enhanced observability and monitoring
Better integration with logging platforms (Datadog, New Relic)
Improved debugging and troubleshooting
Compliance and audit trail capabilities
6. Turbo Offline (Offline-First Applications)
Impact: Medium-High | Status: In
Development
Enable offline-first web and mobile applications with Hotwire.
What it enables:
Progressive Web App (PWA) capabilities
Offline data synchronization
Native mobile app offline support (via Hotwire Native)
Seamless online/offline transitions
Use Cases:
Field service applications
Mobile data collection
Remote work scenarios
Areas with unreliable connectivity
๐ฑ Mobile & Native Developments
Hotwire Native Ecosystem
Rails 8.1 significantly enhances mobile development capabilities:
1. Action Push Native
Official push notification framework
Direct APNs (iOS) and FCM (Android) integration
No third-party dependencies
2. Turbo Offline
Offline-first mobile applications
Data synchronization when online
Seamless UX during connectivity loss
3. Hotwire Native Benefits
Build once, deploy to web + iOS + Android
HTML rendering from Rails server
Native look and feel
Immediate feature parity with website
Development Approach:
Convert existing Rails website to native apps
Minimal additional code required
Shared business logic across platforms
Rapid mobile feature deployment
โ ๏ธ Breaking Changes & Deprecations
Action Dispatch / Routing
REMOVED: Deprecated support for skipping leading brackets
in parameter names