frameworks
July 14, 2026 · 7 min read · 0 views

Rails 8: Solid Queue, Kamal, and the Future of Rails Deployment

Rails 8 ships with built-in job queuing, containerized deployment tools, and a modern authentication system. Here's what changed and how to upgrade.

Rails 8: A Major Step Forward for Modern Web Applications

Rails 8, released in November 2024, represents a significant evolution for the Rails framework. This release introduces three major features that fundamentally change how Rails developers approach job processing, deployment, and authentication: Solid Queue (built-in job queuing), Kamal (containerized deployment), and Authentication Generator (out-of-the-box user auth). These additions reflect the Rails team’s commitment to reducing external dependencies and providing production-ready solutions out of the box.

For developers maintaining Rails applications or starting new projects, Rails 8 offers tangible improvements in operational simplicity, deployment flexibility, and time-to-market. Let’s explore what changed, why it matters, and how to get started.

What’s New in Rails 8

Solid Queue: Built-In Job Processing

For years, Rails developers relied on external job queues like Sidekiq, Resque, or Delayed Job. Solid Queue changes this by providing a production-grade job queuing system as part of Rails itself.

Key features:

  • Database-backed queue: Jobs are stored in your PostgreSQL or MySQL database—no Redis or separate infrastructure required
  • Concurrent processing: Supports multiple processes and threads for parallel job execution
  • Reliable delivery: Built-in retry logic, error handling, and job status tracking
  • Simple configuration: Minimal setup compared to external queue systems

Solid Queue is ideal for applications that:

  • Run on single-server deployments or small clusters
  • Already use PostgreSQL/MySQL and want to reduce infrastructure complexity
  • Have moderate job volumes (thousands to tens of thousands per hour)
  • Want tighter integration with Rails code

Kamal: Container-Based Deployment Without Kubernetes

Kamal, originally extracted from Hey’s deployment infrastructure, is now a first-class Rails tool. It provides an alternative to Kubernetes that’s simpler for small-to-medium teams.

What Kamal does:

  • Docker containers: Automatically builds and deploys Docker images to your servers
  • Zero-downtime deployments: Orchestrates rolling updates with health checks
  • SSH-based deployment: No complex orchestration layer—just SSH and Docker
  • Multi-server support: Deploy to multiple machines with automatic load balancing
  • Cost-effective: Works with any VPS provider (DigitalOcean, Linode, AWS EC2, etc.)

Unlike Kubernetes, Kamal is opinionated and designed specifically for Rails applications, reducing operational overhead.

Authentication Generator

Rails 8 includes a new rails generate authentication command that scaffolds a complete authentication system, including:

  • User model with password hashing (bcrypt)
  • Session management
  • Password reset functionality
  • Email verification (optional)

This addresses a long-standing pain point: every Rails developer had to either write authentication from scratch or integrate Devise, which, while powerful, adds complexity to simple applications.

Getting Started with Rails 8

Creating a New Rails 8 Application

gem install rails --version '~> 8.0'
rails new myapp
cd myapp
bundle install

Rails 8 defaults to using Solid Queue for job processing and includes the authentication generator by default.

Generating Authentication

rails generate authentication
rails db:migrate

This creates:

  • User model with password hashing
  • Authentication routes and controller
  • Session management helpers
  • Migration files

The generated code is intentionally simple and modifiable—not a black-box gem.

Configuring Solid Queue

Basic Setup

Solid Queue is installed by default. Configuration is straightforward:

# config/solid_queue.yml
production:
  dispatchers:
    - batch_size: 500
      polling_interval: 1
  workers:
    - threads: 5
      polling_interval: 1

This configures one dispatcher (sends jobs to workers) and one worker process with 5 concurrent threads.

Enqueuing Jobs

# Define a job
class SendWelcomeEmailJob < ApplicationJob
  queue_as :default

  def perform(user_id)
    user = User.find(user_id)
    UserMailer.welcome(user).deliver_later
  end
end

# Enqueue it
SendWelcomeEmailJob.perform_later(user.id)

# Schedule for later
SendWelcomeEmailJob.set(wait: 1.hour).perform_later(user.id)

This syntax is identical to previous Rails versions, making migration from other queue systems straightforward.

Monitoring Job Status

Solid Queue stores job data in the database, making it queryable:

# Check job counts
SolidQueue::Job.where(status: :pending).count
SolidQueue::Job.where(status: :failed).count

# Find a specific job
job = SolidQueue::Job.find_by(job_id: "abc123")
puts job.error if job.failed?

You can also use API Request Builder to integrate job monitoring with external dashboards by querying Rails endpoints.

Deploying with Kamal

Prerequisites

Kamal requires:

  • Docker installed on your local machine
  • SSH access to your deployment servers
  • A container registry (Docker Hub, GitHub Container Registry, etc.)

Kamal Configuration

Rails 8 generates a config/deploy.yml file:

service: myapp
image: username/myapp

registries:
  docker:
    username: <%= ENV['DOCKER_USERNAME'] %>
    password: <%= ENV['DOCKER_PASSWORD'] %>

servers:
  web:
    hosts:
      - 1.2.3.4
      - 1.2.3.5
  job:
    hosts:
      - 1.2.3.6
    cmd: ./bin/solid_queue start

env:
  clear:
    RAILS_ENV: production
  secret:
    - RAILS_MASTER_KEY
    - DATABASE_URL

volumes:
  - "log:/rails/log"
  - "tmp:/rails/tmp"

traefik:
  image: traefik:v3
  ports:
    - "80:80"
    - "443:443"
  options:
    publish:
      - "443:443/tcp"
      - "80:80/tcp"

Key features:

  • Separate web and job roles for independent scaling
  • Environment variables managed securely
  • Built-in Traefik reverse proxy for TLS and routing

Deploying

# First deployment (sets up servers)
kamal setup

# Redeploy after code changes
kamal deploy

# Roll back to previous version
kamal rollback

# Check logs
kamal logs

# SSH into a server
kamal ssh web

Step-by-Step Upgrade Path

If you’re running Rails 7, upgrading to Rails 8 is relatively straightforward:

1. Update Gemfile

gem 'rails', '~> 8.0'

2. Run Bundle Update

bundle update rails

3. Run Rails Upgrade Command

bundle exec rails app:update

This updates configuration files and generates new files (like Kamalfile) without overwriting your code.

4. Review Breaking Changes

Key breaking changes in Rails 8:

  • Ruby 3.1+: Rails 8 requires Ruby 3.1 or newer
  • Zeitwerk eager loading: Stricter constant loading in development
  • JSON serialization: Default JSON encoder has changed behavior
  • SQLite improvements: New default behavior for SQLite connections

Consult the Rails 8 upgrade guide for detailed instructions.

5. Test Job Processing

If migrating from Sidekiq or another queue:

# In your test suite
require 'rails_helper'

describe SendWelcomeEmailJob do
  it 'sends a welcome email' do
    user = create(:user)
    expect {
      SendWelcomeEmailJob.perform_now(user.id)
    }.to change { ActionMailer::Base.deliveries.count }.by(1)
  end
end

Use perform_now in tests instead of enqueueing, ensuring synchronous execution.

Common Pitfalls and How to Avoid Them

Pitfall 1: Database Bottlenecks with Solid Queue

Problem: If you have extremely high job volumes (100k+ jobs/hour), a database-backed queue may become a bottleneck.

Solution: Solid Queue is ideal for most applications, but if you hit limits, migrate to Sidekiq—job code remains the same:

# Your job code works with both Solid Queue and Sidekiq
class MyJob < ApplicationJob
  queue_as :default
  def perform(*args)
    # code here
  end
end

Pitfall 2: Kamal SSH Access Not Configured

Problem: Kamal relies on SSH keys for server access; misconfigured credentials block deployments.

Solution: Pre-configure SSH keys on all target servers:

# On your local machine
ssh-copy-id -i ~/.ssh/id_rsa [email protected]

# Test connection
ssh [email protected] 'docker --version'

Pitfall 3: Missing Environment Variables in Production

Problem: config/deploy.yml references environment variables; missing ones crash deployments.

Solution: Validate variables before deploying:

kamal env check

And use a .env.production.local file locally:

# .env.production.local
DATABASE_URL=postgresql://...
RAILS_MASTER_KEY=...

Pitfall 4: Not Running Solid Queue in Background

Problem: Forgetting to start the Solid Queue worker process means jobs never process.

Solution: With Kamal, define a separate job role in config/deploy.yml:

servers:
  job:
    hosts:
      - 1.2.3.6
    cmd: ./bin/solid_queue start

Or manually in production:

bin/solid_queue start

Why Rails 8 Matters

Rails 8 represents a philosophical shift: instead of relying on external gems for essential functionality, Rails now bundles production-ready solutions. This has several implications:

  1. Reduced complexity: New developers can start with fewer dependencies
  2. Better integration: Authentication and job processing are tightly integrated with Rails
  3. Easier deployment: Kamal removes the need to learn Kubernetes for most teams
  4. Lower operational costs: Database-backed queuing and SSH-based deployment reduce infrastructure overhead

For small-to-medium teams, Rails 8 can significantly reduce time-to-production and operational burden. For larger teams, the built-in tools provide solid baselines—you can still integrate Sidekiq, Devise, or Kubernetes if needed.

Testing Your Configuration

Before deploying, thoroughly test your setup:

# Test job enqueueing
MyJob.perform_later
assert_enqueued_with(job: MyJob)

# Test Solid Queue processing
require 'solid_queue/testing'
MyJob.perform_now  # In tests, process immediately

For deployment validation, you can use API Request Builder to test endpoints before and after deployment:

# Test health endpoint
curl -X GET https://myapp.com/health

And use Webhook Tester to capture deployment notifications:

# Kamal can POST to a webhook after deployment
kamal deploy
# Your webhook endpoint receives:
# {
#   "event": "deployed",
#   "service": "myapp",
#   "timestamp": "2024-12-15T10:30:00Z"
# }

Conclusion

Rails 8 is a mature release that reflects years of production experience at companies like Basecamp and Hey. Solid Queue, Kamal, and the authentication generator reduce boilerplate and operational complexity without sacrificing flexibility.

For developers upgrading from Rails 7, the migration is straightforward. For new projects, Rails 8 provides a faster path to a deployable application.

The key takeaway: Rails now provides sensible defaults for deployment, job processing, and authentication—you can start simple and add complexity only when you need it.

This post was generated with AI assistance and reviewed for accuracy.