High-performance, SQL-driven background job engine for Odoo.
Documentation | Migration Guide
This repository provides three end-user Odoo modules for background job processing:
- job_worker — Core queue engine with a persistent
queue.jobmodel, SQL pull worker (FOR UPDATE SKIP LOCKED) with PostgreSQLLISTEN/NOTIFYwakeups, channel-level concurrency and rate limiting, and developer APIs compatible withwith_delay()/delayable()patterns. - job_worker_demo — Interactive demo companion for exploring the queue system.
- job_worker_monitor — Dashboard, metrics, and alerting for queue operations.
A fourth module, job_worker_stress, ships test-only job bodies used by the stress suite. It is not auto-installed and is not intended for production.
- Odoo 19.0
- PostgreSQL 12+ (including PostgreSQL 18)
PostgreSQL 18 Note: Version 18 has stricter serialization checks under REPEATABLE READ isolation. This module uses READ COMMITTED isolation for heartbeat and status updates to avoid serialization failures while maintaining correct concurrent behavior.
- Place the
job_worker,job_worker_demo, andjob_worker_monitordirectories in your Odoo addons path. - Update the apps list and install
Job Worker.
odoo -d <db_name> \
--addons-path=/path/to/odoo/addons,/path/to/job-worker-modules \
-i job_worker \
--stop-after-initRun the bundled runner as a dedicated process/service. The runner
(QueueJobRunner) discovers every database with job_worker installed and
supervises a worker per database, restarting crashed workers and writing a
liveness heartbeat file.
Standalone launcher script:
python job_worker_runner.py -c /etc/odoo/odoo.confOr invoke the runner as a module:
python -m odoo.addons.job_worker.cli -c /etc/odoo/odoo.confBoth entry points call QueueJobRunner.from_environ_or_config(), which reads
runner settings from the environment (see the Deployment
and Configuration guides).
For container orchestration, job_worker_healthcheck.py is a fast,
Odoo-free script that exits 0 while the runner's heartbeat file is fresh and
1 otherwise — suitable as a Docker HEALTHCHECK.
Operational notes:
- Workers listen on channel
queue_job_wake_up. - Jobs are recovered if stale (
started+ old/missing heartbeat). - Retry backoff is exponential: 10s, 20s, 40s, ... until
max_retries.
Configure per-channel limits using model queue.limit:
limit: max concurrent jobs.rate_limit: jobs/second (0means unlimited).
Configure in the UI under the Queue menus provided by the module.
- Queue Job User: view and operate their own jobs.
- Queue Job Manager: includes user rights, can view all jobs, and can configure channels.
job = env["queue.job"].enqueue(
model_name="res.partner",
method_name="write",
record_ids=[partner.id],
args=[{"name": "Updated by queue"}],
kwargs={},
channel="root",
priority=10,
max_retries=5,
)job = partner.with_delay(priority=5, channel="exports").write({"name": "Queued"})delayable = partner.delayable(priority=5, channel="exports").write({"name": "Queued"})
job = delayable.delay()eta and scheduled_at are supported aliases for scheduling. If both are provided, they must match.
Use identity_key to collapse duplicate active jobs:
job = env["queue.job"].enqueue(
model_name="res.partner",
method_name="write",
record_ids=[partner.id],
args=[{"name": "Queued once"}],
kwargs={},
identity_key=f"partner:{partner.id}:write_name",
)If a job with the same identity_key already exists in waiting, pending, or started, the existing job is returned.
Each job stores:
user_id: execution user.company_id: execution company.
Worker execution builds context from job metadata (user/company/lang/tz), then executes method calls in that context.
- Requeue failed jobs from the UI (
button_requeue) to reset attempts/error and wake workers. - Use list bulk actions on
Queue Jobs > Jobsfor:- Requeue selected jobs
- Set selected jobs to done
- Set selected jobs to failed
- Inspect fields:
state,attempts,max_retries,exc_info,heartbeat,worker_id. - If jobs are not running:
- Confirm worker process is running.
- Confirm
scheduled_atis not in the future. - Check channel limits (
queue.limit). - Check PostgreSQL connectivity and logs.
Run the test suite using Docker:
bash docker/run_tests.shBugs are tracked on GitHub Issues.
This project is licensed under the LGPL-3.0.