A US SaaS client came to us with one request: get Redis out of the stack. They were already on Rails 8, paying for managed Redis nobody on their team fully understood, and the Rails 8 Solid Queue default looked like a clean way to drop a service from the bill and the on-call runbook. I led the migration off Sidekiq. Four months later, I have the numbers most comparison posts skip, including the morning a routine job sat for 1.2 seconds before it even started running.
This is what actually happened in production, not what the install guide promises. If you're weighing the same switch and want a second set of hands, you can Hire Ruby on Rails Developers who have run this exact migration rather than learning it on your live app. Here's the honest version.
Why Rails 8 Solid Queue Tempts Teams Off Sidekiq
The pitch writes itself. Solid Queue ships as the default Active Job backend in Rails 8 and stores jobs in your existing database using FOR UPDATE SKIP LOCKED, so there's no Redis to provision, patch, or wake up for at 3 AM. For a client running transactional email, webhook deliveries, and nightly report generation, that consolidation is real. One fewer service to monitor. One fewer failure mode. Transactional enqueue, since the job and the data it touches live in the same Postgres.
Cost helped seal it. Solid Queue is open source under the MIT license with every feature included, while Sidekiq reserves batches, unique jobs, and rate limiting for its paid tiers. The official Sidekiq pricing puts Pro at $99 a month and Enterprise starting at $269 a month. For a bootstrapped US SaaS, removing that line item plus the managed Redis bill is real money back in the budget. So the business case for Rails 8 Solid Queue was settled before I wrote a line of code. The engineering case was where it got interesting.
What the Job Pickup Latency Actually Looked Like in Production
Here's the thing nobody flags loudly enough: Solid Queue uses a database polling loop, not a push-based message queue. Workers poll on an interval, claim jobs with an advisory lock, and move on. That design is what frees you from Redis, but it also sets a latency floor that Rails 8 Solid Queue can't engineer away.
In our client's app, pickup time drifted toward a full second under write pressure. The worst I logged was 1.2 seconds between enqueue and start, and not at peak load. Sidekiq, by comparison, picks jobs up in single-digit milliseconds because it's pushing off an in-memory queue. That gap sounds academic until a user feels it.
For this client, it mattered in exactly one place. A user clicked "Export," we enqueued the job, and the second-long pause before the spinner did anything felt broken even though it wasn't. Everything else, the emails and the cleanup tasks and the digests, did not care about a one-second delay. That split is the whole decision in miniature. Throughput was never the constraint either. Solid Queue comfortably handles a few thousand jobs a minute, and this app peaked nowhere near that.
The Migration Path I Used: Queue by Queue, Not Flag-Day
The part that saved me from a bad weekend: both Sidekiq and Solid Queue are Active Job adapters, so they run side by side. You don't cut over everything at once. You route one queue to the new backend, watch it, then move the next. That incremental rollout is the safest way to adopt Rails 8 Solid Queue without risking dropped jobs.
I started with the lowest-risk queue, the mailers, by setting self.queue_adapter = :solid_queue on those job classes while everything else stayed on Sidekiq. A few gotchas surfaced that the docs gloss over:
- Retries don't carry over.
Sidekiq retries automatically; Solid Queue leans on Active Job, so anything that relied on sidekiq_options retry: needs retry_on StandardError, attempts: 3 written explicitly. Miss this and failed jobs just die quietly.
- Recurring jobs move to a config file.
Sidekiq-cron schedules convert to config/recurring.yml, and during overlap you have to disable one source or users get two of every digest email. I gated the old cron behind an env flag and flipped it on the next deploy.
- The hidden cost is database load.
Every poll and every claim is a write. On a busy app you watch Postgres CPU, connection count, and index bloat, not Redis memory. The incident playbook changes with it.
Monitoring also changes. The Sidekiq web UI is gone, replaced by Mission Control Jobs, which I mounted behind admin auth. After two weeks of clean metrics per queue, I moved the rest. No dropped jobs, no flag-day, no rollback needed. That discipline is most of why the Rails 8 Solid Queue switch went smoothly.
When I'd Still Keep Sidekiq Over Rails 8 Solid Queue
I'm not going to pretend this is a clean win for every app. If a client processes well over ten thousand jobs a minute sustained, needs sub-100ms pickup for real-time work, or already runs Redis for caching and Action Cable, the math flips and Sidekiq stays. Solid Queue requires FOR UPDATE SKIP LOCKED, so you also need Postgres 9.5+ or MySQL 8.0+ to even play.
The framework I land on after running both: pick Rails 8 Solid Queue when you're under that throughput band, want one less service, and can tolerate a latency floor measured in hundreds of milliseconds to a second. Keep Sidekiq when latency or volume is genuinely the product. Most apps I see fall in the first bucket, which is exactly why the default changed.
The Verdict After Four Months
For this client, dropping Redis was the right call. The bill went down, the deploy got simpler, and the only latency-sensitive path got moved back to a fast adapter while everything else stayed on the database. That nuance, knowing which queue belongs where, is the difference between a smooth migration and a support fire, and it's the kind of judgment a seasoned Ruby on Rails Development Company brings to a switch like this. If you're sitting on Rails 8 and weighing Rails 8 Solid Queue for your own app, audit your job latency tolerance first, migrate one queue at a time, and let the production numbers, not the defaults, make the final call.
Top comments (2)
we're on rails 8 but still running sidekiq, did the 1.2s pickup delay actually cause problems for real users or was it only noticeable on stuff like exports?
mostly just the export type stuff tbh. emails, cleanup jobs, nightly reports nobody noticed the delay. the one spot it hurt was anything where a user clicks and waits for something to happen right away. we ended up keeping those couple of jobs on sidekiq and moved everything else to solid queue. worked out fine.