NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3017 most downloaded on PyPI
Postgres-based distributed task processing library
Last release 10 days ago
23 Sep 2026
Ships fairly regularly
a new release about every 6 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
4 versions withdrawn
withdrawn after publishing
7 years old
106 releases · first in 2019
> This is the first major release for Procrastinate, and the 50th release of the project. The project has been moving a lot up until 2021, and has slo
A word from the maintainer:
This is the first major release for Procrastinate, and the 50th release of the project. The project has been moving a lot up until 2021, and has slowed down since. In the last year or so, it was almost dormant. One of the reasons was the poor state of sync vs async compatibility code, which made new contributions more complex. It took a few month to gather the motivation for solving this, but the release of the excellent
Psycopg3, as well as the opportunity to useasgiref's sync/async compatibility code opened the door for new solutions.This release wouldn't have existed without the help of the users who gave their opinion in #882, and especially @paulzakin and their team who tested beta versions in real-life scenarios.
I'd love for the procrastinate developer team to be bigger, as I'm the only person committing to the project these days (... except for dependency bots, of course). If you use Procrastinate in your life, and would like to give back a little bit of time now and then, please don't hesitate to come say hi (#748).
Happy new year, happy upgrading, and let us know if anything breaks :) Cheers, Joachim
None
The following is a consequence of the merge of #753 (see also #882)
Aiopg and Psycopg2 connectors are now contrib. To use them, you'll need to import them with from procrastinate.contrib.aiopg import AiopgConnector and from procrastinate.contrib.psycopg2 import Psycopg2Connector. Also, the dependencies to aiopg and psycopg2 are now optional: use pip install procrastinate[aiopg] or pip install procrastinate[psycopg2] (or pip install procrastinate[aiopg,psycopg2] for both)PsycopgConnector that uses Psycopg 3 (and SyncPsycopgConnector). Please note that PsycopgConnector accepts parameters based on psycopg_pool.ConnectionPool, which has a slightly different signature from the psycopg2/aiopg counterpart, the main difference is that the connection arguments are now passed as PsycopgConnector(kwargs={"host": "..."}) (instead of AiopgConnector(host=...)). Other parameters may have changed too, please check the documentation.PsycopgConnector (or AiopgConnector), see if it works with all your existing code and don't hesitate to report potential issues. Synchronous connectors are still available in case you need it, so it should be a workaround in most cases.asgiref.sync_to_async. That said, because of the Global Interpreter Lock (GIL), CPU-consuming tasks will not run faster with parallelization.JobManager.check_connection was an async method. It became check_connection_async for consistency. check_connection was created a the sync counterpart.@paulzakin for testing, and the folks who contributed to #882
One column per quarter.
Nothing published for this version
Aiopg and Psycopg2 connectors are now contrib. To use them, you'll need to import them with from procrastinate.contrib.aiopg import AiopgConnector and
None
#753 :
Aiopg and Psycopg2 connectors are now contrib. To use them, you'll need to import them with from procrastinate.contrib.aiopg import AiopgConnector and from procrastinate.contrib.psycopg2 import Psycopg2Connector. Also, the dependencies to aiopg and psycopg2 are now optionnal: use pip install procrastinate[aiopg] or pip install procrastinate[psycopg2] (or pip install procrastinate[aiopg,psycopg2] for both)PsycopgConnector that use Psycopg 3 (and SyncPsycopgConnector)PsycopgConnector (or AiopgConnector).asgiref.sync_to_async.procrastinate defer x --unknown {} and now you'll have to put all positional arguments first and flags last: procrastinate defer x {} --unknown. We can't guarantee that there won't be other subtle breaks around this (e.g. environment variable support). That said, if you discover a change, feel free to open a ticket, if it's easily fixable, we might fix it.Discussion about these changes happen in https://github.com/procrastinate-org/procrastinate/discussions/882
Don't throw an importError if psycopg(3) can't be imported, unless user is actually using it
None
@ashleyheath
Ensure jobs are scheduled for retry regardless of exception type raised
None
@ashleyheath
(We needed a new version number for administrative reasons)
(We needed a new version number for administrative reasons)
https://github.com/procrastinate-org/procrastinate/tree/main/procrastinate/sql/migrations
https://github.com/procrastinate-org/procrastinate/tree/main/procrastinate/sql/migrations
@aleksandr-shtaub
Set encoding=utf-8 when reading files to avoid warnings
None
#868, #870, #867, #866, #864, #862, #861, #860, #858, #859, #857, #855, #856, #853, #851, #850, #847, #848, #872, #849
@ashleyheath
When a job ends with an exception, but it's retried, instead of logging the exception at "ERROR" level, it logs as "INFO" level.
None
@ashleyheath
Add complete details on how to integrate with Django
None
@adibsaad, @mininao, @paulzakin and @turicas 👏
When using Python < 3.9, Procrastinate is not compatible anymore with importlib_resources < 1.4
None
When using Python < 3.9, Procrastinate is not compatible anymore with importlib_resources < 1.4 (#724)
[pre-commit.ci] pre-commit autoupdate
None
This time, the Deploy workflow will work!
None
friendly error for get_full_path failures
None
@abe-winter
SQL Alchemy integrity Error (& hole in coverage)
None
schedule_in docstring (#595)There should be much less noise in the future thanks to Renovate.
Thank you @abe-winter for multiple contributions! 🎉 Thank you @pmav99 for a first public PR ever in this repo! 🎉
## Migrations None ## Changelog - Fix deploy workflow
None
This PR doesn't add a new migration, *however*, it fixes an issue with a previous release where a migration was created and didn't have the proper nam
This PR doesn't add a new migration, however, it fixes an issue with a previous release where a migration was created and didn't have the proper name, ending up not being advertised in the changelog.
This is the migration:
If you're unsure whether you need to apply the migration or not, here's a rundown:
@benjamb
https://github.com/procrastinate-org/procrastinate/blob/master/procrastinate/sql/migrations/00.22.00_01_add_kwargs_to_defer_periodic_job.sql
The following migration should have been part of the 0.23 release, but due to a naming error, it wasn't originally displayed as such. Here is a link to the migration as it was when the tag was issued:
periodic_id: https://procrastinate.readthedocs.io/en/latest/howto/cron.html#scheduling-a-job-multiple-times-with-multiple-arguments . Also, if you relied on the fact that periodic schedules configures on the same task but with different queues were seen as independent schedules (https://github.com/procrastinate-org/procrastinate/blob/0.22.0/docs/howto/cron.rst#queue-lock-queuing-lock or #289), you will probably need to update your code and define unique periodic_ids in addition to the queues.@aleksandr-shtaub
See the documentation for details. Note that if you used blueprints from Procrastiate 0.21, this is a breaking change.
None (TODO: replace if there are migrations) https://github.com/procrastinate-org/procrastinate/tree/master/procrastinate/sql/migrations
This release officially adds Blueprints with their supported API. See the documentation for details. Note that if you used blueprints from Procrastiate 0.21, this is a breaking change.
Also, starting with this version, when the worker cannot function correctly (e.g. when it looses access to the database), it will crash instead of entering a half-broken state. This way, you get to define your own restart strategy, with back-off etc, the way you want.
App.with_connector lets you create multiple synchronized apps with different connectors, in case you need to support both a sync and an async app.
In procrastinate shell, a new list_locks command lets you find out about task locks that are currently set, to simplify the hunting for longstanding locks.
Support for python3.6 has been removed, support for python3.10 has been added.
Documentation has been updated regarding where you should place your app. In particular, in case you put your app in the module whose __name__ is __main__, a warning is now emitted, because this could lead to issues.
Periodic tasks used to all share a lock, so no 2 periodic tasks could run at the same time. This is now fixed.
And finally, did you notice ? The repository moved to the procrastinate-org organization, yay !
@tomdottom, @elemoine, @ewjoachim
Remove auto-loading of tasks (#425): before this version, if a task was not loaded as a side effect of the app, and its module was not specified in th
None
import_paths parameters of the app, and a worker received that task, it tried as a last-resort attempt, to load this task through its name. This meant that someone controlling a task name could make the worker load any code. The feature was removed altogether.
If your worker emited warnings like Task at {task_name} was not registered, it's been loaded dynamically. (with log action load_dynamic_task), it means you need to change the code for it to work. If the warning was not emitted, you're good to go.@mecampbellsoup and @tomdottom
https://github.com/peopledoc/procrastinate/blob/master/procrastinate/sql/migrations/00.19.00_01_add_index_on_procrastinate_jobs.sql
@elemoine, @ioben, and Mickaël Guérin
Make it possible to define additional context on the worker
None
@elemoine, @ewjoachim and @mxd4
The following migration fixes a schema bug introduced in 0.18.0. Please make sure to deploy this migration at the same time as the migrations mentione
The following migration fixes a schema bug introduced in 0.18.0. Please make sure to deploy this migration at the same time as the migrations mentioned in 0.18.0.
@BracketJohn
:warning: If you plan to deploy 0.18.1, consider deploying 0.18.2 instead, as its migrations contain a fix for a 0.18.0 migration that could cause som
:warning: If you plan to deploy 0.18.1, consider deploying 0.18.2 instead, as its migrations contain a fix for a 0.18.0 migration that could cause some bugs.
No migrations in bugfix releases.
@BracketJohn and @tmartinfr
https://github.com/peopledoc/procrastinate/blob/master/procrastinate/sql/migrations/00.16.00_01_add_finish_job_and_retry_job_functions.sql (this migra
:warning: These migration contain an incompatibility that is resolved in 0.18.2. Please run the migrations mentioned in 0.18.0 and 0.18.2 as a bundle to avoid potential downtimes
sync and async example more complete (#368)@BracketJohn, @ignaciocabeza, @mxd4
This version didn't actually add new migrations (but existing migrations were renamed)
This version didn't actually add new migrations (but existing migrations were renamed)
A consequence of this, if you're using Django Migrations and ran migrations pre-0.17 is that one of the Django migrations was renamed, which confuses Django. Before running the Migrations for 0.17.0, you're invited to run the following Django code in the Django shell (manage.py shell):
>>> from django.db.migrations.recorder import MigrationRecorder
>>> MigrationRecorder.Migration.objects.filter(app="procrastinate", name="0001_baseline").update(name="0001_initial")
Starting at this release, migrations can be run while the system runs, provided certain conditions are met. See the migrations doc for more information.
Work on migrations:
procrastinate healthchecks now doesn't report the number of jobs anymore. Use procrastinate shell for that.@elemoine, @ewjoachim and @thomasperrot
https://github.com/peopledoc/procrastinate/blob/master/procrastinate/sql/migrations/delta_0.15.2_001_fix_procrastinate_defer_periodic_job.sql
@elemoine, @ewjoachim, @mgu and @thomasperrot
Once again, this release is just a way for us to test the release process. Nothing changed in the code.
Once again, this release is just a way for us to test the release process. Nothing changed in the code.
None
@thomasperrot
https://github.com/peopledoc/procrastinate/blob/master/procrastinate/sql/migrations/delta_0.14.0_001_add_locks_to_periodic_defer.sql
@ewjoachim and @thomasperrot
Fix the "every second periodic task" bug
None
Agate (ping @EliotBerriot), @t-eckert, @elemoine, @ewjoachim
Very slight possible breaking change: the code parsing dates when calling procrastinate defer --at= has changed. If you were using ISO8601 strings, no…
None
procrastinate defer --at=<date> has changed. If you were using ISO8601 strings, nothing changed. If you were using more exotic formats, we think that nothing changed, but we don't have a definitive proof of that, so here's a warning. See https://procrastinate.readthedocs.io/en/stable/howto/schedule.html?highlight=pendulum#from-the-code (#279)@EliotBerriot
https://github.com/peopledoc/procrastinate/blob/master/procrastinate/sql/migrations/delta_0.11.0_003_add_procrastinate_periodic_defers.sql
@SBillion, @elemoine, @ewjoachim and @tmartinfr
https://github.com/peopledoc/procrastinate/blob/master/procrastinate/sql/migrations/delta_0.10.0_001_close_fetch_job_race_condition.sql
AiopgConnector with maxsize=0 or 1, it used to change it to 2. Now it won't. 0 should really be avoided. 1 will disable the listen/notify feature. See doc.Psycopg2Connector() and have real synchronous I/Os, likely to work better with multithreaded programs. See doc. (#237)return <something> in your task to make this <something> appear in your logs (#252)listen_notify=False in your worker configuration (#258)@elemoine and @ewjoachim
A bug (#236) since 0.7.1 was preventing the listen-notify feature from working correctly.
A bug (#236) since 0.7.1 was preventing the listen-notify feature from working correctly.
None
@elemoine and @ewjoachim
Rename PostgresConnector into AiopgConnector (#225):
Rename PostgresConnector into AiopgConnector (#225):
The class PostgresConnector became AiopgConnector. The only change is the name.
Add notion of "queueing lock" (#219):
Queueing locks can ensure periodic jobs do not accumulate in the queue: at any given time, only a single job with a given queueing lock can be waiting.
See https://procrastinate.readthedocs.io/en/latest/howto/cron.html#launch-a-task-periodically
Now, the release process is as documented.
Now, the release process is as documented.
https://github.com/peopledoc/procrastinate/blob/0.8.0/procrastinate/sql/migrations/delta_0.7.1_001_fix_trigger_status_events_insert.sql
Change CREATE FUNCTION to CREATE OR REPLACE FUNCTION in the delta_0.6.0_001_fix_procrastinate_fetch_job.sql migration script.
Change CREATE FUNCTION to CREATE OR REPLACE FUNCTION in the delta_0.6.0_001_fix_procrastinate_fetch_job.sql migration script.
Add a "Use Pum for migrations" how-to #170
Call close_connection from procrastinate_demo main #158
App is now initialized with a PostgresConnector object instead of a PostgresJobStore.
App is now initialized with a PostgresConnector object instead of a PostgresJobStore.
Change your code from:
app = procrastinate.App(job_store=procrastinate.PostgresJobStore(dsn="..."))
to
app = procrastinate.App(connector=procrastinate.PostgresConnector(dsn="..."))
:warning: We're going to change a few details around that in the next versions, if you want to avoid frequent changes and you don't need this release, it might be worth waiting for the next ones. We'll advertise when we thing the App API is likely stable.
Don't overwrite psycopg2 adapters when creating the connection
Fixing long description on PyPI
Launch tasks when they're corountines (but still sequentially)
- First release on PyPI
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →