Getting started

Quick start

Configure, run an ActiveJob, publish an event, start workers, and mount the dashboard.

1. Configure (optional)#

pgbus works with zero config in Rails.

pgbus uses your existing Active Record connection, so it runs with no configuration. For custom setups, drop a Ruby initializer:

config/initializers/pgbus.rb
Pgbus.configure do |c|
  c.queue_prefix       = "myapp"
  c.max_retries        = 5
  c.visibility_timeout = 30.seconds   # ActiveSupport::Duration accepted
  c.idempotency_ttl    = 7.days

  # Worker recycling — prevents long-lived processes from leaking memory
  c.max_jobs_per_worker = 10_000
  c.max_memory_mb       = 512
  c.max_worker_lifetime = 1.hour

  # Capsule string DSL — Sidekiq-style "queues: threads; queues: threads"
  c.workers = "default, mailers: 10; critical: 5"
end

The full set of knobs is in Configuration and the Configuration reference.

2. Use as the ActiveJob backend#

Point Active Job at pgbus:

config/application.rb
config.active_job.queue_adapter = :pgbus

That's it — your existing jobs work unchanged:

app/jobs/order_confirmation_job.rb
class OrderConfirmationJob < ApplicationJob
  queue_as :mailers

  def perform(order)
    OrderMailer.confirmation(order).deliver_now
  end
end

# Enqueue
OrderConfirmationJob.perform_later(order)

# Schedule
OrderConfirmationJob.set(wait: 5.minutes).perform_later(order)

3. Publish an event (optional)#

Publish with AMQP-style topic routing:

Pgbus.publish(
  "orders.created",
  { order_id: order.id, total: order.total }
)

Subscribe with an idempotent handler:

app/handlers/order_created_handler.rb
class OrderCreatedHandler < Pgbus::EventBus::Handler
  idempotent! # deduplicate by (event_id, handler_class)

  def handle(event)
    order_id = event.payload["order_id"]
    Analytics.track_order(order_id)
  end
end

# Register in an initializer
Pgbus::EventBus::Registry.instance.subscribe("orders.created", OrderCreatedHandler)

# Wildcard patterns: orders.# matches orders.created, orders.shipped.confirmed, …
Pgbus::EventBus::Registry.instance.subscribe("orders.#", OrderAuditHandler)

The full routing and idempotency story is in Event bus.

4. Start workers#

Boot the supervisor, which manages workers (ActiveJob queues), the dispatcher (maintenance), and event consumers:

bundle exec pgbus start

See Running workers for recycling, roles, and the CLI flags.

5. Mount the dashboard#

Mount the engine to see queues, jobs, processes, failures, and dead letters — auto-refreshing over Turbo Frames, no WebSocket:

config/routes.rb
mount Pgbus::Engine => "/pgbus"
Protect the dashboard in production — a web_auth lambda or a base_controller_class that inherits your app's authentication. See Dashboard.