Migrate

From Sidekiq

Drop Redis, switch the adapter, and map Sidekiq's Pro/Enterprise features onto pgbus.

What changes#

Sidekiq brokers through Redis; pgbus brokers through PostgreSQL (PGMQ). The migration removes Redis and gives you dead-letter queues, worker recycling, and an event bus on your existing database.

Effort: low if you use ActiveJob exclusively; medium-high if you have native Sidekiq workers or lean on Pro/Enterprise features.

Swap the gem and adapter#

Gemfile
# Remove
gem "sidekiq"
gem "sidekiq-cron"        # if used
gem "sidekiq-unique-jobs" # if used

# Add
gem "pgbus"
bundle install && rails generate pgbus:install && rails db:migrate
config/application.rb
config.active_job.queue_adapter = :pgbus # was :sidekiq

Convert native workers#

ActiveJob jobs work unchanged; native workers need a rewrite.

If every job already inherits ApplicationJob, you're done — they run unchanged. A native Sidekiq::Job becomes a standard ActiveJob:

# Before — native Sidekiq worker
class HardWorker
  include Sidekiq::Job
  sidekiq_options queue: :critical, retry: 5
  def perform(user_id, action) = ...
end

# After — ActiveJob
class HardWorker < ApplicationJob
  queue_as :critical
  retry_on StandardError, wait: :polynomially_longer, attempts: 5
  def perform(user_id, action) = ...
end

API mapping#

SidekiqActiveJob / pgbus
perform_async(args)perform_later(args)
perform_at(time, args).set(wait_until: time).perform_later(args)
perform_in(duration, args).set(wait: duration).perform_later(args)
sidekiq_options queue:queue_as
sidekiq_options retry: Nretry_on StandardError, attempts: N
sidekiq_retries_exhausteddiscard_on + after_discard

Middleware → ActiveJob callbacks#

Sidekiq middleware becomes ActiveJob callbacks. Server middleware maps to before_perform / around_perform / after_perform; client middleware to the *_enqueue callbacks:

class ApplicationJob < ActiveJob::Base
  around_perform do |job, block|
    Rails.logger.info("Starting #{job.class.name}")
    block.call
    Rails.logger.info("Finished #{job.class.name}")
  end
end

What you gain#

And where the Pro/Enterprise features land.

Sidekiq featurepgbus equivalent
Batches (Pro)Pgbus::Batch
Concurrency (Enterprise)limits_concurrency
Unique jobs (Enterprise)ensures_uniqueness
Cron (sidekiq-cron)Recurring tasks (fugit)
Sidekiq WebDashboard

Plus what Sidekiq never had: dead-letter queues, worker recycling, an event bus, and no Redis.

Gotchas#

  • Argument serialization — Sidekiq passes raw JSON; ActiveJob uses GlobalID for Active Record objects. Passing ids (user.id) behaves the same; passing records (user) serializes via GlobalID automatically.
  • Sidekiq.redis { ... } — if you used Sidekiq's Redis for custom locks or caching, move to PostgreSQL advisory locks or another store.
  • Queue priority — Sidekiq uses queue weights; pgbus processes queues in the order listed, so put higher-priority queues first (or use priority queues).