DEV Community

Cover image for Goodbye Redis? The Rise of Solid Queue in Rails 8
Zil Norvilis
Zil Norvilis

Posted on

Goodbye Redis? The Rise of Solid Queue in Rails 8

The "Redis Tax" is Over

For the last decade, the standard Rails stack looked like this:

  1. Rails (App)
  2. PostgreSQL (Data)
  3. Redis (Cache & Jobs)

We almost always added Redis just to run Sidekiq. While Sidekiq is an incredible piece of software, maintaining a separate data store just for background jobs increases infrastructure complexity and cost—especially for small-to-medium applications.

Enter Rails 8. With the introduction of Solid Queue and Mission Control, Rails is officially endorsing the return of Database-Backed Jobs—but this time, they are fast.

What is Solid Queue?

Solid Queue is a DB-based queuing backend.

In the past (think delayed_job), DB queues were frowned upon because polling the database was slow and caused table locking issues. Solid Queue solves this by utilizing modern SQL features like FOR UPDATE SKIP LOCKED. This allows workers to pick up jobs atomically without blocking other workers and without hammering the database.

It is now the default queue adapter in Rails 8 production environments.

Step 1: Installation

If you are running rails new my_app with Rails 8, you already have this.

If you are upgrading from Rails 7, or want to add it manually:

# Gemfile
gem "solid_queue"
gem "mission_control-jobs"
Enter fullscreen mode Exit fullscreen mode

Run the setup:

bundle install
rails solid_queue:install
rails db:migrate
Enter fullscreen mode Exit fullscreen mode

This creates a few tables in your database (prefixed with solid_queue_) to handle jobs, scheduled tasks, and failures.

Step 2: Configuration

Tell Rails to use Solid Queue as the backend.

# config/environments/production.rb
config.active_job.queue_adapter = :solid_queue
Enter fullscreen mode Exit fullscreen mode

(Note: In development, you might still use :async (in-memory), but I recommend using :solid_queue locally too, to catch serialization bugs early.)

You can configure your workers and dispatchers in config/solid_queue.yml. The default is usually sufficient for most apps:

# config/solid_queue.yml
default:
  dispatchers:
    - polling_interval: 1
      batch_size: 500
  workers:
    - queues: "*"
      threads: 3
      polling_interval: 0.1
Enter fullscreen mode Exit fullscreen mode

Step 3: Mission Control (The Dashboard)

One of the biggest reasons devs stuck with Sidekiq was the Web UI. It was hard to live without seeing your failed jobs.

Rails now provides Mission Control: Jobs. It’s a dashboard that lets you view queues, pause workers, and retry failed jobs.

To set it up, mount the engine in your routes:

# config/routes.rb
Rails.application.routes.draw do
  # ... your other routes
  mount MissionControl::Jobs::Engine, at: "/jobs"
end
Enter fullscreen mode Exit fullscreen mode

🔒 Securing the Dashboard

Do not deploy this without authentication. You don't want the public pausing your email workers.

Wrap the route in a constraint or use Basic Auth. Here is the simplest way using Rails' built-in Basic Auth in your routes.rb:

# config/routes.rb
MissionControl::Jobs::Engine.base_controller_class = "ApplicationController"

Rails.application.routes.draw do
  # Basic Auth wrapper
  scope "admin" do
    mount MissionControl::Jobs::Engine, at: "/jobs", constraints: ->(request) {
      ActiveSupport::SecurityUtils.secure_compare(
        request.env["HTTP_AUTHORIZATION"].to_s, 
        ActionController::HttpAuthentication::Basic.encode_credentials("admin", ENV["JOBS_PASSWORD"])
      )
    }
  end
end
Enter fullscreen mode Exit fullscreen mode

(Alternatively, if you use a User model with an admin? boolean, you can use a lambda constraint.)

Step 4: Running the Workers

In the past, you had to run bundle exec sidekiq. Now, you run:

bundle exec rake solid_queue:start
Enter fullscreen mode Exit fullscreen mode

If you are using the new Rails 8 bin/dev (or Overmind/Foreman), add this to your Procfile.dev:

web: bin/rails server
worker: bundle exec rake solid_queue:start
Enter fullscreen mode Exit fullscreen mode

Why Switch?

  1. Simplicity: One less service (Redis) to provision, monitor, and pay for.
  2. Transactional Integrity: If your Rails app is in a transaction and you enqueue a job, Solid Queue (being in the same DB) waits for the commit. No more "Job started before the record existed" race conditions.
  3. Native: It respects Active Record connections and configurations right out of the box.

Conclusion

Redis is still amazing and necessary for massive scale or heavy caching needs. But for the vast majority of Rails applications, Solid Queue is fast enough, cheaper to run, and easier to maintain.

The "One Person Framework" just got a whole lot more powerful.


Are you sticking with Sidekiq or moving to Solid Queue? Let’s argue in the comments below! 👇

Top comments (0)