The "Redis Tax" is Over
For the last decade, the standard Rails stack looked like this:
- Rails (App)
- PostgreSQL (Data)
- 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"
Run the setup:
bundle install
rails solid_queue:install
rails db:migrate
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
(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
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
🔒 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
(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
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
Why Switch?
- Simplicity: One less service (Redis) to provision, monitor, and pay for.
- 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.
- 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)