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#
# 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:migrateconfig.active_job.queue_adapter = :pgbus # was :sidekiqConvert 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) = ...
endAPI mapping#
| Sidekiq | ActiveJob / 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: N | retry_on StandardError, attempts: N |
sidekiq_retries_exhausted | discard_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
endWhat you gain#
And where the Pro/Enterprise features land.
| Sidekiq feature | pgbus equivalent |
|---|---|
| Batches (Pro) | Pgbus::Batch |
| Concurrency (Enterprise) | limits_concurrency |
| Unique jobs (Enterprise) | ensures_uniqueness |
| Cron (sidekiq-cron) | Recurring tasks (fugit) |
| Sidekiq Web | Dashboard |
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).