Upgrading to v1.7
This release introduces database-backed workflow tracking, replaces generated columns with expression indexes, and adds new partial indexes for improved performance. The guide covers running the required migration, optional cleanup steps for reclaiming storage, switching deprecated callbacks, and enabling usage rules for AI coding assistants.
If you're upgrading from Oban to Pro for the first time, you can jump straight to v1.7 without any concern about table locking from generated columns.
Bump Your Deps
Update Oban and Pro to the latest versions:
{:oban_pro, "~> 1.7.0-rc.0", repo: "oban"},Run Oban.Pro.Migration (Required)
Generate a new migration:
mix ecto.gen.migration upgrade_oban_pro_to_1_7
Within the generated migration module:
use Ecto.Migration
def up, do: Oban.Pro.Migration.up(version: "1.7.0")
def down, do: Oban.Pro.Migration.down(version: "1.7.0")For large tables, split the schemas and indexes migrations so indexes can be created
concurrently:
mix ecto.gen.migration upgrade_oban_pro_schemas_to_1_7
mix ecto.gen.migration upgrade_oban_pro_indexes_to_1_7
defmodule MyApp.Repo.Migrations.UpgradeObanProSchemasTo17 do
use Ecto.Migration
def up, do: Oban.Pro.Migration.up(version: "1.7.0", only: :schemas)
def down, do: Oban.Pro.Migration.down(version: "1.7.0", only: :schemas)
end
defmodule MyApp.Repo.Migrations.UpgradeObanProIndexesTo17 do
use Ecto.Migration
@disable_migration_lock true
@disable_ddl_transaction true
def up, do: Oban.Pro.Migration.up(version: "1.7.0", only: :indexes)
def down, do: Oban.Pro.Migration.down(version: "1.7.0", only: :indexes)
endSee the Oban.Pro.Migration module docs for additional options.
Switch Workflow Callbacks (Recommended)
The Oban.Pro.Workflow.after_cancelled/2 callback is deprecated in favor of the universal
Oban.Pro.Worker.on_cancelled/2 hook. Currently, both hooks will be called if defined, so you
should switch to on_cancelled/2 to avoid duplicate execution:
defmodule MyApp.MyWorker do
use Oban.Pro.Worker, queue: :default
- @impl Oban.Pro.Workflow
- def after_cancelled(%Oban.Job{} = job, reason) do
+ @impl Oban.Pro.Worker
+ def on_cancelled(%Oban.Job{} = job, reason) do
Logger.info("Job #{job.id} cancelled: #{inspect(reason)}")
:ok
end
endDrop Generated Columns (Recommended)
After upgrading to v1.7, the uniq_key and partition_key generated columns are no longer used.
You can optionally drop them to simplify your schema and reclaim storage space.
Generate a migration:
mix ecto.gen.migration drop_oban_generated_columns
Then add the column removals:
defmodule MyApp.Repo.Migrations.DropObanGeneratedColumns do
use Ecto.Migration
def change do
alter table(:oban_jobs) do
remove_if_exists :uniq_key, :text
remove_if_exists :partition_key, :text
end
end
endCockroachDB Users
CockroachDB does not support expression indexes with function calls in the WHERE clause. If
you are using CockroachDB, you must keep the generated columns and use the generated_columns: true option when running migrations:
def up, do: Oban.Pro.Migration.up(version: "1.7.0", generated_columns: true)Drop Legacy Workflow Indexes (Recommended)
The v1.7 migration creates new workflow, sub-workflow, and chain indexes that use the suspended
state instead of the old on_hold pseudo-state. The old indexes are renamed with an _old suffix
and can be dropped after the migration completes.
Generate a migration:
mix ecto.gen.migration drop_oban_legacy_workflow_indexes
Then drop the indexes concurrently:
defmodule MyApp.Repo.Migrations.DropObanLegacyWorkflowIndexes do
use Ecto.Migration
@disable_migration_lock true
@disable_ddl_transaction true
def change do
drop_if_exists index(:oban_jobs, [:id], name: :oban_jobs_workflow_index_old, concurrently: true)
drop_if_exists index(:oban_jobs, [:id], name: :oban_jobs_sup_workflow_index_old, concurrently: true)
drop_if_exists index(:oban_jobs, [:id], name: :oban_jobs_chain_index_old, concurrently: true)
end
endEnable Usage Rules (Optional)
Oban Pro v1.7 ships with usage rules—reference documents that help coding agents understand Pro's idioms and best practices. If you use Claude Code, Cursor, etc., enable usage rules to get better suggestions when working with Pro.
Add the usage_rules package to your dependencies:
{:usage_rules, "~> 1.2"}Then configure it in mix.exs to include Oban Pro's rules:
defp usage_rules do
[
usage_rules: [:oban_pro, ...]
]
endThen run:
mix deps.get && mix usage_rules.sync
Re-run mix usage_rules.sync after upgrading Pro to get updated rules.
Drop Args and Meta GIN Indexes (Optional)
The args and meta GIN indexes were added by earlier Oban migrations for ad-hoc querying, but
they are not required for normal operation. These indexes can be quite large, and removing them may
reclaim significant storage space.
Generate a migration:
mix ecto.gen.migration drop_oban_gin_indexes
Then drop the indexes concurrently:
defmodule MyApp.Repo.Migrations.DropObanGinIndexes do
use Ecto.Migration
@disable_migration_lock true
@disable_ddl_transaction true
def change do
drop_if_exists index(:oban_jobs, [:args], name: :oban_jobs_args_index, concurrently: true)
drop_if_exists index(:oban_jobs, [:meta], name: :oban_jobs_meta_index, concurrently: true)
end
endBefore Dropping
Only drop these indexes if you don't query jobs by arbitrary args or meta fields. The
specialized indexes Pro uses for workflows, chains, etc. will remain and be used internal
queries.