Solid Queue: Rails jobs backed by the database you already run
Database-backed Active Job backend
At a glance
- What is it?
- Rails ships its own database-backed Active Job backend. Here is what Solid Queue actually asks of you, what it borrows from Active Job, and where the operational edges are.
- Who is it for?
- Solid Queue makes the most sense for an application already committed to Rails and to a relational database, because the only new infrastructure it asks for is a second database on the same server and a bin/jobs process to supervise. Sidekiq and GoodJob remain the right answer when Redis is already present or when the queue has to outlive the application framework.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 29 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A job backend that is really just tables and a process
The pitch for Solid Queue is short enough to state in one line: it is the Active Job backend Rails now configures by default, and it stores work in your SQL database rather than in Redis. For applications that already have MySQL, PostgreSQL or SQLite, that removes an entire piece of infrastructure from the deployment. There is no broker to install, no Lua scripting, no separate memory profile to tune, and no second failure domain during an incident at three in the morning.
What you give up is the specialised data structure that made Redis queues fast. Solid Queue works around this by leaning on the database rather than fighting it. The README notes that it uses the FOR UPDATE SKIP LOCKED clause where available, which lets several worker processes claim jobs without blocking each other on row locks. That clause is standard on PostgreSQL and MySQL 8, so the common production case is covered well. SQLite is supported too, which makes local development and small single-server deployments straightforward.
The important structural point is that Solid Queue is not a replacement for Active Job. The README is explicit that it relies on Active Job for retries, discarding, error handling, serialization and delays. What Solid Queue adds is the storage and dispatch layer: delayed jobs, concurrency controls, recurring jobs, paused queues, numeric priorities per job, ordering by queue priority, and bulk enqueuing for Active Job's perform_all_later. If you are already writing jobs as plain Active Job classes, moving to Solid Queue changes your adapter setting rather than your job code.
Installing means adding a database and a second process
The install is two commands. For a Rails 8 application nothing is needed, because the generator has already run. For an earlier version the README gives the minimum supported versions as Rails 7.1 and Ruby 3.2.
bundle add solid_queue
bin/rails solid_queue:installThe generator configures Solid Queue as the production Active Job backend, creates config/queue.yml and config/recurring.yml, writes db/queue_schema.rb, and adds a bin/jobs wrapper executable. That last point is the one to internalise: Solid Queue is a separate long-running process, and someone has to keep it alive. In production that means a supervisor, a systemd unit or a container that is not the web server.
There is a second consequence, and it is the one most people hit first. The queue lives in its own database, so config/database.yml needs a second entry with its own migrations path. For SQLite the shape is straightforward:
production:
primary:
<<: *default
database: storage/production.sqlite3
queue:
<<: *default
database: storage/production_queue.sqlite3
migrations_paths: db/queue_migrateAfter that, db:prepare in production creates the database and loads the schema. A useful detail buried in the README: the install generator only writes the connects_to line into config/environments/production.rb. If you want the backend in development or staging too, you have to add the equivalent adapter and connects_to lines yourself and set up the database entries for those environments. Action Cable, and anything built on it such as Turbo Streams, needs the same treatment because it also needs a database rather than an in-memory adapter.
Priorities, concurrency limits and the cost of both
The feature that most distinguishes Solid Queue from a bare table-backed queue is concurrency control, and it is also the one with a documented performance caveat. You declare how many jobs of a given class or queue may run at once, and the dispatcher respects that limit by holding semaphore slots. The v1.7.0 release notes are worth reading closely here, because a contributor clarified that combining concurrency controls with bulk enqueuing is a performance caveat rather than an unsafe combination. That is a reassuring revision of an earlier characterisation, and it tells you the interaction was tested in production applications rather than only in the test suite.
Priorities work at two levels, which the README treats as separate mechanisms. Jobs carry a numeric priority, and queues are declared in order so that higher priority work is dispatched first. The combination lets an application shape both the internal ordering of a backlog and the order in which queues are serviced.
The other documented performance lever is queue specification, and the guidance is that declaring specific queues performs better than a catch-all. If you let a worker process everything by default, it polls across every queue in the table on each pass. Naming the queues a given worker should service narrows those polls, which matters more as the queue table grows.
One operational note belongs here too. The README states that future schema changes will arrive as regular migrations, and v1.5.1 added a generator specifically to copy new migrations into existing installations. That is a reasonable design, but it means queue schema upgrades are a deployment step you schedule rather than something that happens automatically.
Three releases, and a repository that is mostly tests
With 2,496 stars and 252 forks, Solid Queue is not a speculative project. What is striking is the release history: the repository lists three releases. v1.5.1 on 29 July 2026 was a patch fixing flaky tests around leaked job threads and signal timing, and it added the migration update generator along with an --only-recurring flag for running just the scheduler. v1.6.0 on 31 July 2026 added fiber execution mode. v1.7.0 on 21 August 2026 added job batches.
Both feature releases arrived within a month of each other and within weeks of each other being requested, which suggests a project that was developed for a long time behind version numbers that were not published as formal releases. The repository tree is consistent with a mature codebase: an UPGRADING.md at the root, an Appraisals file, a gemfiles/ directory for dependency matrix testing, a .devcontainer for local setup, and a docker-compose.yml that pins MySQL 8.0.31 and PostgreSQL 15.1 for the test matrix. What is not visible in a shallow look is much application code, because there is not much to show. The tree is mostly app/, lib/, config/, bin/ and test/.
The fiber mode from v1.6.0 deserves attention because it is not a small addition. Instead of a thread pool running jobs in multiple threads per worker, a worker can run jobs as fibers on a single reactor thread, backed by the Async library. It suits I/O-bound work such as jobs that spend their time waiting on external API calls. The trade-offs are specific: Async becomes a dependency, and the Rails application has to use fiber isolation. Workers configured this way are declared with a fiber count rather than a thread count. If your jobs are CPU-bound, the original thread and process model remains the right choice.
Recurring tasks, batches and what the dashboard gives you
Recurring tasks live in config/recurring.yml, the second file the installer creates, and they can be scheduled and unscheduled at runtime rather than only at boot. This is the feature that most directly displaces a separate scheduler process, since cron, Sidekiq Enterprise's scheduled sets or a dedicated scheduler container all become unnecessary for work that runs on a simple interval.
Batches, added in v1.7.0, give Active Job's perform_all_later a place to put its bookkeeping. The README documents batch progress and counters, maintenance operations, and a way to clear batches once they are no longer interesting. The release notes credit a community contributor for both the feature and its refinements against production applications, which is a reasonable signal that the semantics were exercised outside the test suite.
On observability, the situation is more modest. The configuration section covers a logger you can redirect, and the installation section points at a dashboard UI setup step, but the repository carries no topics and no homepage in its metadata, and the documentation for the dashboard lives with Rails rather than in this repository. If you are comparing Solid Queue to Sidekiq, the honest summary is that Sidekiq ships a considerably more developed operational surface: a web UI, per-queue inspection, and retry tooling are its default. Solid Queue's answer is that you already have the database and you already have query tools. For a small team that is a fine trade; for a team with someone whose job is watching the queue, it is not.
The development experience is tidier than the production one. The README documents a Puma plugin that starts Solid Queue alongside the web server, gated on an environment variable or on Rails.env.development?, which removes the need for a second process in local development without weakening production supervision.
Deciding between Solid Queue, Sidekiq and GoodJob
The comparison comes down to what is already in your stack. Solid Queue is at its best when the application is a Rails app, the datastore is relational, and the team would rather not operate Redis. Its failure modes are the database's failure modes, which for most teams is an advantage because there is one thing to back up and one set of credentials to rotate.
GoodJob makes a similar argument with a Postgres-specific emphasis, and it is a closer architectural cousin than Sidekiq. Sidekiq is the different proposition: Redis-native, with the most mature feature set around scheduling, retries and inspection of the ecosystem. Choosing it means accepting Redis as a required component of a correctly running application.
Two Solid Queue capabilities deserve a check against your workload before you decide. Concurrency controls are how you stop a job class from exhausting a downstream API or a database connection pool, and they are the feature that makes this more than a table with a poller on top. Recurring tasks are how you delete a scheduler. If neither matters to you, a plain database queue would cover the basics and Solid Queue's advantage narrows.
Finally, plan the queue database deliberately. It needs its own connection, its own migrations path and its own backup consideration, and the README's own advice for small projects is to run Solid Queue on the same machine as the webserver. Horizontal scaling works out of the box once you are past that, including the option of designating machines to run only dispatchers or only workers, so the growth path is not the constraint. The constraint is the first deployment.
Editorial conclusion
Solid Queue makes the most sense for an application already committed to Rails and to a relational database, because the only new infrastructure it asks for is a second database on the same server and a bin/jobs process to supervise. Sidekiq and GoodJob remain the right answer when Redis is already present or when the queue has to outlive the application framework. Whichever you pick, the three things worth checking before committing are the separate queue database, the schema migration story for a project that has only shipped three releases, and whether your jobs are I/O bound enough to justify the fiber mode that arrived in v1.6.0.
Frequently asked questions
What is a solid queue in Rails?
Solid Queue is the database-backed Active Job backend that Rails configures by default in new Rails 8 applications. It stores queued jobs in MySQL, PostgreSQL or SQLite tables instead of Redis, and adds concurrency controls, priorities, recurring tasks and batches on top of Active Job's retries, serialization and error handling.
How to run a solid queue?
Run the bin/jobs executable the installer creates, supervised as its own long-running process. The installer wires it up with bundle add solid_queue and bin/rails solid_queue:install, and you still need a second database entry in config/database.yml with its own migrations path before db:prepare loads the queue schema.
Does Solid Queue need a separate Redis instance?
No. Redis is not a dependency. Solid Queue polls your SQL database and uses the FOR UPDATE SKIP LOCKED clause where the engine supports it, so the new infrastructure is a queue database and a worker process rather than a broker.
When is Sidekiq a better fit than Solid Queue?
Sidekiq is the better fit when Redis is already part of your infrastructure and you want its scheduling, retry and inspection tooling rather than assembling it from database queries. Solid Queue suits teams that would rather keep a relational database as the only stateful dependency.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rails-solid-queue)