View Source Upgrading to v2.11

This Oban release includes a required migration and a couple of optional, but recommended, changes.


Bump Your Deps

Update Oban, Web, and Pro to the latest versions:

  {:oban, "~> 2.11"},
  {:oban_pro, "~> 0.10", repo: "oban"},
  {:oban_web, "~> 2.9", repo: "oban"}


Run Oban.Migrations for v11

Oban's new leadership mechanism uses an unlogged table to track state globally. The v11 migration creates a new oban_peers table, and is required for leadership—without it many plugins won't run.

To get started, create a migration to create the table:

$ mix ecto.gen.migration create_oban_peers

With in the generated migration module:

use Ecto.Migration

def up, do: Oban.Migrations.up(version: 11)

def down, do: Oban.Migrations.down(version: 11)

If you have multiple Oban instances or use an alternate prefix you'll need to run the migration for each prefix.

The Oban.Peer module will safely handle a missing oban_peers table and log a warning.


Update Notifier Names

Now that we've pulled the PG notifier in from Oban Pro there are a few naming changes you should make.

  1. If your config explicitly declares Oban.PostgresNotifier, change it to the new namespaced version: Oban.Notifiers.Postgres:
-notifier: Oban.PostgresNotifier
+notifier: Oban.Notifiers.Postgres
  1. If you are using Pro's PG notifier, change it to the new namespaced version from Oban:
-notifier: Oban.Pro.Notifiers.PG
+notifier: Oban.Notifiers.PG


Check Configuration for Multi-Node Setups

This release introduces centralized leadership through the Oban.Peer behaviour. To prevent duplicate plugin work across nodes, only one Oban instance within a cluster may be the leader. Unfortunately, if a node that doesn't run plugins becomes the leader then jobs may get stuck as available and plugins like Cron or Pruner won't run.

The simplest solution is avoid plugins: false altogether:

-plugins: false
+plugins: []

See the Troubleshooting guide for more context.

Oban uses a single compound index for most queries. The index is comprised of job state, queue, priority, scheduled_at, and id. That single index is flexible enough to power most of Oban's queries. However, the column order is important, and the order created by Oban's migrations isn't optimal in all situations.

If you're experiencing slow plugin queries, e.g. the Stager, then you may benefit from swapping the indexes. To do so, create a migration:

$ mix ecto.gen.migration swap_primary_oban_indexes

Within the generated migration module:

@disable_ddl_transaction true
@disable_migration_lock true

def change do
  create_if_not_exists index(
    [:state, :queue, :priority, :scheduled_at, :id],
    concurrently: true,
    prefix: "public"

  drop_if_exists index(
    [:queue, :state, :priority, :scheduled_at, :id],
    concurrently: true,
    prefix: "public"

Be sure to reference the correct prefix if your oban_jobs table uses a prefix other than public.