Ror Background Jobs
title: Ruby on Rails Background Jobs — Complete Guide to Active Job description: 'Learn Ruby on Rails background jobs: Active Job, Sidekiq, Solid Queue, job scheduling, mailer delivery, recurring jobs, and monitoring with Sidekiq UI.' date: 2026-06-28 lastmod: 2026-06-28 weight: 29 tags: [backend, ror]
Rails background jobs handle time-consuming tasks (email, file processing, API calls) asynchronously using Active Job with backends like Sidekiq (Redis) or SolidQueue (database).
## What You'll Learn
By the end of this tutorial, you'll create and enqueue jobs, configure Sidekiq and SolidQueue, schedule recurring jobs, handle failures with retries, and monitor job queues.
## Real-World Use
An e-commerce app processes order confirmations, generates PDF invoices, syncs inventory with warehouse systems, and sends weekly analytics emails — all via background jobs.
## Background Jobs Learning Path
```mermaid
flowchart LR
A[Mailers] --> B[Background Jobs]
B --> C[Caching]
C --> D[Security]
D --> E[Docker]
B --> F{You Are Here}
style F fill:#f90,color:#fff
Creating a Job
rails generate job process_payment
rails generate job send_welcome_email
# Creates app/jobs/application_job.rb and app/jobs/*_job.rb
# app/jobs/process_payment_job.rb
class ProcessPaymentJob < ApplicationJob
queue_as :default
retry_on PaymentGatewayError, wait: :polynomially_longer, attempts: 5
discard_on InvalidPaymentError
def perform(order_id)
order = Order.find(order_id)
service = PaymentService.new(order)
result = service.charge!
if result.success?
OrderMailer.payment_confirmation(order).deliver_now
order.update!(paid_at: Time.current)
else
raise PaymentGatewayError, result.error_message
end
end
end
Enqueuing Jobs
# From controller
class OrdersController < ApplicationController
def create
@order = Order.new(order_params)
if @order.save
ProcessPaymentJob.perform_later(@order.id) # Default queue
ProcessPaymentJob.set(wait: 1.hour).perform_later(id) # Delayed
ProcessPaymentJob.set(queue: :urgent).perform_later(id) # Different queue
SendWelcomeEmailJob.perform_later(@order.user)
redirect_to @order, notice: "Order placed!"
end
end
end
# Set priority globally
class ApplicationJob < ActiveJob::Base
sidekiq_options retry: 5, queue: :default
end
Sidekiq Setup
# Gemfile
gem "sidekiq"
gem "sidekiq-cron" # Recurring jobs
# config/routes.rb
require "sidekiq/web"
Rails.application.routes.draw do
mount Sidekiq::Web => "/sidekiq" # Job monitoring dashboard
end
# config/routes.rb (with auth)
authenticate :user, ->(u) { u.admin? } do
mount Sidekiq::Web => "/sidekiq"
end
# config/application.rb
config.active_job.queue_adapter = :sidekiq
# config/sidekiq.yml
:concurrency: 5
:queues:
- [critical, 5]
- [default, 3]
- [mailers, 2]
- [low, 1]
# Run Sidekiq worker
bundle exec sidekiq
# Visit /sidekiq for dashboard
Recurring Jobs
# config/initializers/sidekiq_cron.rb
Sidekiq::Cron::Job.create(
name: "Weekly report",
cron: "0 9 * * 1", # Every Monday 9 AM
class: "WeeklyReportJob"
)
Sidekiq::Cron::Job.create(
name: "Cleanup expired sessions",
cron: "0 0 * * *", # Every midnight
class: "CleanupSessionsJob"
)
# app/jobs/weekly_report_job.rb
class WeeklyReportJob < ApplicationJob
queue_as :low
def perform
User.find_each do |user|
WeeklyReportMailer.report(user).deliver_later
end
end
end
Solid Queue (Database Backend)
# Gemfile (Rails 8 default)
gem "solid_queue"
# config/application.rb
config.active_job.queue_adapter = :solid_queue
# config/solid_queue.yml
default: &default
dispatcher:
polling_interval: 1
batch_size: 500
worker:
queues:
- [critical, 5]
- [default, 3]
- [mailers, 1]
development:
<<: *default
production:
<<: *default
# Install and run
rails solid_queue:install
bundle exec rake solid_queue:work
Common Mistakes
1. Passing Complex Objects to Jobs
Pass record IDs (user.id) not objects (user). Jobs serialize arguments as JSON.
2. Jobs That Are Too Large
A job should do one thing. If a job has multiple responsibilities, split it.
3. Not Handling Failures
Without retry_on, failed jobs are lost. Always configure retry policies.
4. Ignoring Queue Priorities
All jobs in the default queue causes delays. Use multiple queues with priorities.
5. Not Monitoring Jobs
Without monitoring (Sidekiq UI or Solid Queue dashboard), silent failures go unnoticed.
Practice Questions
1. What is Active Job?
Rails' standard interface for background jobs. Works with various backends (Sidekiq, SolidQueue, Delayed Job).
2. How do you delay job execution?
Use .set(wait: 1.hour).perform_later or .set(wait_until: Date.tomorrow.noon).perform_later.
3. What is the difference between Sidekiq and Solid Queue?
Sidekiq uses Redis (faster, more features). Solid Queue uses the database (simpler, no Redis dependency).
4. How do you handle job failures?
Use retry_on for retryable errors, discard_on for permanent failures, and rescue for error logging.
5. Challenge: Create a job that processes weekly email reports and retries 3 times on failure.
class WeeklyDigestJob < ApplicationJob
queue_as :low
retry_on Net::SMTPError, wait: 5.minutes, attempts: 3
def perform
User.active.find_each do |user|
DigestMailer.weekly(user).deliver_later
end
end
end
FAQ
Mini Project: Background Email Job
Create a job that sends welcome emails in the background with Sidekiq.
rails generate job send_welcome_email
# Implement perform(user_id)
# Enqueue from UsersController create action
# Start Sidekiq: bundle exec sidekiq
class SendWelcomeEmailJob < ApplicationJob
queue_as :mailers
def perform(user_id)
user = User.find(user_id)
UserMailer.welcome(user).deliver_now
end
end
What's Next
Ruby on Rails Caching Ruby on Rails Security
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro