Upgrading to v1.8
This release introduces workflow compensations, cursor-based backfills, inline cron annotations, external recorded storage, and persisted pruning rules with archiving. It also adopts Oban's dedicated service configuration and replaces the chain and chunk indexes for improved performance.
A database migration is required. All configuration changes are optional and can be adopted incrementally.
Bump Your Deps
Update Oban and Pro to the latest versions:
{:oban, "~> 2.24"},
{:oban_pro, "~> 1.8.0", repo: "oban"},Run Oban.Pro.Migration (Required)
Oban Pro v1.8 drops _old indexes created by the v1.7 migration, adds tables for persisted
Oban.Pro.Pruner rules and archived jobs, columns for workflow compensations, and an index for
backfills. Generate a new migration and run Oban.Pro.Migration:
defmodule MyApp.Repo.Migrations.UpgradeObanProToV180 do
use Ecto.Migration
def up, do: Oban.Pro.Migration.up(version: "1.8.0")
def down, do: Oban.Pro.Migration.down(version: "1.8.0")
endOn large oban_jobs tables, split the schema and index changes so indexes are created
concurrently without blocking writes:
defmodule MyApp.Repo.Migrations.UpgradeObanProSchemasToV180 do
use Ecto.Migration
def up, do: Oban.Pro.Migration.up(version: "1.8.0", only: :schemas)
def down, do: Oban.Pro.Migration.down(version: "1.8.0", only: :schemas)
endThen run the index migration outside a transaction:
defmodule MyApp.Repo.Migrations.UpgradeObanProIndexesToV180 do
use Ecto.Migration
@disable_migration_lock true
@disable_ddl_transaction true
def up, do: Oban.Pro.Migration.up(version: "1.8.0", only: :indexes)
def down, do: Oban.Pro.Migration.down(version: "1.8.0", only: :indexes)
endThe migration lock doesn't need to be disabled when the repo uses advisory migration locks.
Rename the Smart Engine (Recommended)
The Smart engine is now Oban.Pro.Engine. Update your configuration to use the shorter module
name:
config :my_app, Oban,
- engine: Oban.Pro.Engines.Smart
+ engine: Oban.Pro.EngineThe old module remains available for compatibility and won't emit deprecation warnings.
Move Dynamic Plugins to Dedicated Options (Recommended)
Oban v2.24 adds top-level options for cron, lifeline, and pruner, while queues accepts the
same {module, options} form. Move the corresponding Pro modules out of :plugins and use their
shorter names:
config :my_app, Oban,
- queues: false,
- plugins: [
- {Oban.Pro.Plugins.DynamicCron, crontab: [...]},
- Oban.Pro.Plugins.DynamicLifeline,
- {Oban.Pro.Plugins.DynamicPruner, mode: {:max_age, {7, :days}}},
- {Oban.Pro.Plugins.DynamicQueues, queues: [default: 10]}
- ]
+ cron: {Oban.Pro.Cron, crontab: [...]},
+ lifeline: Oban.Pro.Lifeline,
+ pruner: {Oban.Pro.Pruner, mode: {:max_age, {7, :days}}},
+ queues: {Oban.Pro.Queues, queues: [default: 10]}The old modules and :plugins configuration remain available and won't emit deprecation warnings
on startup. However, calls to runtime management functions on the old modules are deprecated, and
you should use the corresponding functions on Oban.Pro.Cron, Oban.Pro.Pruner, or
Oban.Pro.Queues instead.
Replace Pruner Overrides with Rules (Optional)
The mode and *_overrides options still work and are automatically translated into rules. To
use compound matches, explicit ordering, runtime updates, or archiving, replace all legacy options
with rules at the same time:
pruner: {
Oban.Pro.Pruner,
- mode: {:max_age, {7, :days}},
- queue_overrides: [events: {:max_age, {10, :minutes}}],
- state_overrides: [discarded: {:max_age, {2, :days}}],
- worker_overrides: ["MyApp.SecretWorker": {:max_age, {1, :second}}]
+ rules: [
+ [name: "queue-events", queue: :events, max_age: {10, :minutes}],
+ [name: "state-discarded", state: :discarded, max_age: {2, :days}],
+ [name: "worker-MyApp.SecretWorker", worker: MyApp.SecretWorker, max_age: {1, :second}],
+ [name: "default", max_age: {7, :days}]
+ ]
}Rules use first-match precedence, so preserve the legacy queue, state, worker, and default order
unless you intentionally want different behavior. Don't combine rules with mode or any
*_overrides; mixed configuration prevents the Pruner from starting.
Add the Mix Compiler for Cron Annotations (Optional)
Cron discovery is registered at compile time by a Mix compiler. Add :oban_pro to your
project's compilers: list after the standard Mix compilers so the worker beams exist when it
scans:
def project do
[
...,
+ compilers: Mix.compilers() ++ [:oban_pro]
]
endIn umbrella projects, add it to each child app that defines annotated workers.
If a worker or decorated function uses cron: without the compiler in place, the first compile
will warn you with the same instructions.
Pair Cron Annotations with Automatic Sync (Optional)
When you start using cron: on workers or decorators, also set sync_mode: :automatic on the
plugin so removed or renamed annotations clean up their persisted entries:
cron: {
Oban.Pro.Cron,
+ sync_mode: :automatic,
crontab: [...]
}Without automatic sync, removing a cron: annotation leaves an orphaned database row that has to
be deleted manually (or with a one-off delete: true entry).
See Discovering Annotated Workers and Automatic Synchronization for full details.
Switch Chunks to process_chunk/1 (Optional)
Chunk workers now have a dedicated process_chunk/1 callback that receives the list of jobs.
Defining process/1 with a list argument continues to work, but process_chunk/1 is preferred
because it doesn't overload the single-job callback shared by all Pro workers.
-@impl Oban.Pro.Worker
+@impl Oban.Pro.Chunk
-def process([_ | _] = jobs) do
+def process_chunk(jobs) do
...
endAdd the Pruner Hash Column (RC Only)
Skip this section unless you ran Oban.Pro.Migration on a v1.8 release candidate. Pruner rules
now store a hash to track config changes, and the oban_pruners table created in the release
candidates lacks that column. The v1.8.0 migration won't add it because the table already exists,
and the Pruner will fail to start without it.
Generate a migration to add the column:
defmodule MyApp.Repo.Migrations.AddHashToObanPruners do
use Ecto.Migration
def change do
alter table(:oban_pruners) do
add_if_not_exists :hash, :text
end
end
end