How SolidQueue Integrates with ActiveJob?

ActiveJob is Rails' built-in abstraction for background job execution. It standardizes the way jobs are declared, enqueued, and performedregardless 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:

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 automaticallywithout 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:

🔧 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 ActiveJobno 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.