How SolidQueue Integrates with ActiveJob?
ActiveJob is Rails' built-in abstraction for background job execution. It standardizes the way jobs are declared, enqueued, and performed — regardless of the backend you choose (e.g., Sidekiq, DelayedJob, or SolidQueue). This allows Rails developers to switch backends with minimal code changes.
When using SolidQueue, you continue writing jobs the same way as with any other backend.
Here’s a basic example:
class ReportJob < ApplicationJob
queue_as :default
def perform(report_id)
report = Report.find(report_id)
report.generate!
end
end
💡 Can
perform
be named differently?No. The
perform
method is required. ActiveJob defines a standard interface that expects this method. Internally, it instantiates your job class and calls.perform
on it when the job is executed. Naming it anything else will break job execution.
To enqueue this job:
ReportJob.perform_later(Report.first)
This enqueues the job to SolidQueue's job table for asynchronous execution.
If you want to run it immediately:
ReportJob.perform_now(Report.first)
This bypasses the queue and runs it synchronously in the current process.
1. Using ActiveJob with SolidQueue
To use SolidQueue with ActiveJob, set it as your backend in config/application.rb
:
config.active_job.queue_adapter = :solid_queue
That’s it. All perform_later
or deliver_later
calls across your app will now use SolidQueue without any extra setup.
2. Email Delivery with SolidQueue
Emails in Rails use ActionMailer, which integrates directly with ActiveJob.
For example:
UserMailer.with(user: user).welcome_email.deliver_later
When using deliver_later
, Rails enqueues a job behind the scenes using the configured adapter — in this case, SolidQueue. This means:
deliver_later
→ callsperform_later
on a generated mailer job.- That job eventually calls the
perform
method, which delivers the email.
So, even though you don’t see perform
directly when calling deliver_later
, it’s still used internally by ActiveJob’s mailer job.
3. Queue Names and Prioritization
SolidQueue supports multiple queues and queue-specific priorities. You can define which queue to use for any job:
class CriticalJob < ApplicationJob
queue_as :critical
end
You can then launch worker processes targeting specific queues:
bin/rails solid_queue:work --queues=critical,default
The order matters. SolidQueue will prioritize critical
over default
here.
This flexibility is powerful in systems with mixed workloads — you can isolate low-priority jobs and avoid them slowing down more important ones.
4. Retry, Discard, and Error Handling
SolidQueue doesn't reimplement retry logic. Instead, it defers to ActiveJob's built-in mechanisms. You can define retries like this:
class PaymentJob < ApplicationJob
retry_on SomeTransientError, attempts: 3
discard_on PermanentFailure
end
SolidQueue will honor these semantics, storing job failure info and retry attempts in the database.
5. Serialization and Deserialization
SolidQueue supports all of ActiveJob’s serialization features — including global ID for ActiveRecord models. So when you pass in User.find(1)
, the job stores a signed reference to the user, and resolves it later at execution time:
class SendReminderJob < ApplicationJob
def perform(user)
user.send_reminder!
end
end
SendReminderJob.perform_later(User.find(1))
No extra setup is needed. This works out of the box with SolidQueue.
5. Zero-Setup Development: No Extra Server Required
One of the best parts about SolidQueue is how seamlessly it works in development. Unlike Sidekiq, which requires a separate Redis server and background worker to be running, SolidQueue can process jobs inline during development — out of the box.
When you’re in the development environment and run:
bin/rails server
SolidQueue uses a thread-based inline worker, meaning your jobs are picked up and executed in the background automatically — without needing to start a separate worker process.
You can enqueue jobs as usual:
WelcomeEmailJob.perform_later(user.id)
And they’ll be processed within the Rails server process while you’re building locally. This is a huge boost to developer experience:
- No Redis to install.
- No
sidekiq
orresque
processes to run. - No risk of forgetting to start your background processor.
- You can even inspect your jobs right from the console:
ruby SolidQueue::Job.last
🔧 Behind the scenes, SolidQueue spins up an internal
Rails::SolidQueue::PollerThread
that polls the database every few seconds and dispatches jobs in a new thread. This mirrors production behavior while keeping your dev environment dead simple.
Of course, for production, you’d want to run a dedicated SolidQueue worker process using:
bin/rails solid_queue:work
But for development? It just works — and feels completely native to Rails.
SolidQueue seamlessly plugs into ActiveJob — no behavioral changes, no learning curve. It brings native queuing into your Rails application while letting you use the clean, declarative ActiveJob DSL you’re already used to.
Whether you're sending emails, scheduling reports, or retrying failed tasks, SolidQueue’s integration with ActiveJob ensures your jobs stay Rails-native, maintainable, and production-ready.