Migrate

# From SolidQueue

Both are PostgreSQL ActiveJob adapters — swap the config and gain LISTEN/NOTIFY, DLQs, and recycling.

## What changes

SolidQueue and pgbus share an architecture — a supervisor/worker model, `FOR UPDATE SKIP LOCKED` polling, forked processes. Both are pure ActiveJob adapters, so your jobs work unchanged. pgbus adds LISTEN/NOTIFY for instant wake-up (SolidQueue only polls), dead-letter queues, worker recycling, and an event bus, and stores messages in PGMQ rather than custom tables.

**Effort:** low.

## Swap the gem and adapter

```ruby
# Remove
gem "solid_queue"
gem "mission_control-jobs" # if used

# Add
gem "pgbus"
```

```shell
bundle install && rails generate pgbus:install && rails db:migrate
```

```ruby
config.active_job.queue_adapter = :pgbus # was :solid_queue
```

> **Note:** If you ran SolidQueue in a separate database via `config.solid_queue.connects_to`, the pgbus equivalent is `config.connects_to` — see [Separate database](https://pgbus.zoolutions.llc/docs/separate-database).

## Convert the worker config

SolidQueue's `processes: N` forks N identical workers; in pgbus you list the same worker entry N times (one per process), or use the capsule DSL:

```ruby
Pgbus.configure do |c|
  # SolidQueue: queues "critical", threads 5, processes 2
  c.workers = "critical: 5; critical: 5; default, low: 3"
  c.max_jobs_per_worker = 10_000
  c.max_memory_mb       = 512
end
```

## Configuration mapping

| SolidQueue | pgbus | Notes |
| --- | --- | --- |
| `polling_interval` | `polling_interval` | Defaults to 0.1s; LISTEN/NOTIFY makes it a fallback. |
| `threads` | `threads` | Same concept. |
| `processes: N` | Repeat the worker entry | One entry per forked process. |
| `queues: "a,b"` | `queues: [a, b]` | Array, not a comma string. |
| `queues: "*"` | List queues explicitly | PGMQ queues are explicit. |

> **Tip:** SolidQueue's `limits_concurrency` has a near-identical pgbus API (auto-included, no explicit require). See [Concurrency & uniqueness](https://pgbus.zoolutions.llc/docs/concurrency-uniqueness); recurring.yml maps to [Recurring tasks](https://pgbus.zoolutions.llc/docs/recurring-tasks).

## What you gain

- **LISTEN/NOTIFY** — instant wake-up instead of polling latency.
- **Dead-letter queues** — SolidQueue has none; pgbus routes exhausted jobs to a `_dlq` queue.
- **Worker recycling** — memory, job-count, and lifetime limits.
- **An event bus** — pub/sub with topic routing, on the same infrastructure.