Adoption
Oban Pro layers enhanced functionality on top of Oban through extensions, plugins, and workers. Those enhancements are all optional and require a little configuration to enable.
This guide will walk you through the minimum configuration changes you should make to start utilizing Pro along with some optional suggestions to hint at what's possible.
1. Pro Engine
The Pro engine is the brains behind much of Pro's advanced capabilities and added reliability. It brings global concurrency limits, distributed rate limiting, partitioned limiting, unique bulk job inserts, and precise orphaned job rescuing.
The Pro engine utilizes centralized producer records to coordinate between nodes with minimal load on the database (and without any reliance on Distributed Erlang clustering).
To start, create a migration:
$ mix ecto.gen.migration add_oban_pro
Within the migration module:
use Ecto.Migration
def up, do: Oban.Pro.Migration.up()
def down, do: Oban.Pro.Migration.down()This creates the various tables and indexes used by Pro's engine and plugins.
Next, update your config to use the Pro engine:
config :my_app, Oban,
+ engine: Oban.Pro.Engine,
repo: MyApp.Repo
...💡 Explore Queue Options
Apply global concurrency limits across all nodes—e.g. a genuinely global
limit: 1Throttle queue throughput by rate limiting to a maximum number of jobs within a period of time.
Partition global or rate limits within a queue by worker, args, meta, or sub-keys.
2. Pro Services
Pro ships drop-in replacements for Oban's built-in Cron, Lifeline, and Pruner services. Each
keeps the same core behavior while adding runtime configuration and Pro engine awareness. Swap
all three at once by pointing the service keys at their Pro counterparts and moving any options
into the service tuple:
config :my_app, Oban,
engine: Oban.Pro.Engine,
- cron: [crontab: [...]],
- lifeline: Oban.Plugins.Lifeline,
- pruner: [max_age: {7, :days}]
- 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]}
...Lifeline rescues orphaned jobs from producer records rather than a time-based grace period, so it's always accurate and no longer needs
rescue_after.Cron uses the same
crontab, but persists entries so you can add, update, or remove them at runtime.Pruner replaces a single global age with per-state, per-queue, and per-worker rules;
modesets the default retention.
💡 Explore Services and Plugins
Use Queues as the top-level
:queuesservice to define and reconfigure queues at runtime, and have those changes persist between restarts.Keep low-priority jobs from starving with DynamicPrioritizer, which gradually bumps their priority until they run.
Autoscale cloud infrastructure to match demand with DynamicScaler, spinning nodes up during traffic and back down during a lull.
3. Pro.Worker
The Oban.Pro.Worker is a replacement for Oban.Worker with expanded capabilities such as
encryption, enforced structure, output recording, and execution hooks.
Upgrade all of your workers to Pro workers by switching out the use module and replacing
perform/1 with process/1:
def MyApp.Worker do
- use Oban.Worker
+ use Oban.Pro.Worker
- @impl Oban.Worker
- def perform(%Job{} = job) do
- # Do stuff with the job
- end
+ @impl Oban.Pro.Worker
+ def process(%Job{} = job) do
+ # Do stuff with the job
+ end
endOnly Pro workers support execution hooks, which are especially helpful as a reliable alternative
to telemetry for error reporting. Once you've modified existing workers you can define a global
error hook (be sure to remove any existing telemetry backed error hooks):
defmodule MyApp.ErrorHook do
def after_process(state, job) when state in [:discard, :error] do
error = job.unsaved_error
extra = Map.take(job, [:attempt, :id, :args, :max_attempts, :meta, :queue, :worker])
Sentry.capture_exception(error.reason, stacktrace: error.stacktrace, extra: extra)
:ok
end
def after_process(_state, _job), do: :ok
end
Oban.Pro.Worker.attach_hook(MyApp.ErrorHook)💡 Explore Pro Workers
Validate args on insert and atomize them during execution with structured jobs.
Stash a job's return value to retrieve it later manually or as part of a workflow with recorded jobs.
Store all job data at rest with encrypted jobs so that sensitive data can't be seen in the clear.
Execute callbacks synchronously, from within the job's process after jobs finish executing with worker hooks
Process jobs in groups while tracking overall progress with Batches.
Compose jobs together with arbitrary dependencies using Workflows.
Process jobs in strict sequential order regardless of retries using Chains
4. Oban.Pro.Testing
Switch from Oban.Testing to Oban.Pro.Testing to more easily test workers, drain queues
reliably, supervise test instances, and make assertions about enqeueud jobs.
defmodule MyApp.Case do
use ExUnit.CaseTemplate
using do
quote do
- use Oban.Testing, repo: MyApp.Repo
+ use Oban.Pro.Testing, repo: MyApp.Repo
end
end
endSwitch to drain_jobs/1
Oban.Pro.Testing.drain_jobs/1 replaces the standard Oban.drain_queue/2. The Pro version is
designed to work with Pro workers and composition tools such as Workflows.
- %{success: 3} = Oban.drain_queue(queue: :default)
+ %{completed: 3} = Oban.Pro.Testing.drain_jobs()The Pro version returns counts using the actual job statuses, or even the full jobs rather than a count.
Continue with the testing guide for additional setup tips, or skip straight into the
Oban.Pro.Testing docs to explore all of the testing functions.
5. Usage Rules (Optional)
Oban Pro ships with usage rules—reference documents that help AI coding assistants understand Pro's idioms and best practices. If you use Claude Code, Cursor, Windsurf, or similar tools, 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
The rules cover workers, queues, composition (workflows, batches, chains, chunks), plugins, and
testing. Re-run mix usage_rules.sync after upgrading Pro to get updated rules.