Control the way synchronous calls to defer are handled

In some cases, usually linked to multi-threading (see Synchronous deferring), you may want to defer tasks purely synchronously (what is called “classic” synchronous I/O).


By setting your App’s connector to an instance of Psycopg2Connector, you will get “classic” synchronous I/O. Note that in this case, some App features will be unavailable, such as the shell and worker sub-commands:

import procrastinate

app = procrastinate.App(

It is perfectly fine to give the App either kind of connectors depending on the situation:

import sys, procrastinate

# This is an example condition, you'll need to check that it works in your case
if sys.argv[0:2] == ["procrastinate", "worker"]:
    connector_class = procrastinate.AiopgConnector
    connector_class = procrastinate.Psycopg2Connector

app = procrastinate.App(

How does it work?

The synchronous connector will use a psycopg2.pool.ThreadedConnectionPool (see psycopg2 documentation), which should fit most workflows.


If you use SQLAlchemy in your synchronous application, you may want to use an SQLAlchemyPsycopg2Connector from the contrib.sqlalchemy module instead. The advantage over using a Psycopg2Connector is that Procrastinate can use the same SQLAchemy engine (and connection pool) as the rest of your application, thereby minimizing the number of database connections.

from sqlalchemy import create_engine

from procrastinate import App
from procrastinate.contrib.sqlalchemy import SQLAlchemyPsycopg2Connector

engine = create_engine("postgresql+psycopg2://", echo=True)

app = App(connector=SQLAlchemyPsycopg2Connector())

Having multiple apps

If you need to have multiple connectors interact with the tasks, you can create multiple synchronized apps with App.with_connector:

import procrastinate

app = procrastinate.App(

sync_app = app.with_connector(

If you do this, you can then register or defer tasks on either app.