Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Run PostgreSQL user-defined database functions in a cron like fashion.




Demo of the example in install.sql: (


To run your functions using pgcronjob, your function must return the pgcronjob-defined ENUM type BatchJobState, which has two values, 'AGAIN' or 'DONE'. This is how your function tells pgcronjob if it wants to be run AGAIN or if the work has completed and we are DONE. A boolean return value would have worked as well, but boolean values can easily be misinterpeted while the words AGAIN and DONE are much more precise, so hopefully this will help avoid one or two accidents here and there.


Run until an error is encountered (DEFAULT):

SELECT cron.Register('cron.Example_Random_Error(integer)', _RetryOnError := NULL);

Try again after 1 second if an error is encountered:

SELECT cron.Register('cron.Example_Random_Error(integer)', _RetryOnError := '1 second'::interval);

Allow concurrent execution (DEFAULT):

SELECT cron.Register('cron.Example_Random_Sleep(integer)', _Concurrent := TRUE);

Detect and prevent concurrent:

SELECT cron.Register('cron.Example_Random_Sleep(integer)', _Concurrent := FALSE);

Wait 100 ms between each execution (DEFAULT):

SELECT cron.Register('cron.Example_No_Sleep(integer)', _IntervalAGAIN := '100 ms'::interval);

No waiting, execute again immediately:

SELECT cron.Register('cron.Example_No_Sleep(integer)', _IntervalAGAIN := '0'::interval);

Run cron job in one single process (DEFAULT):

SELECT cron.Register('cron.Example_No_Sleep(integer)', _Processes := 1);

Run cron job concurrently in two separate processes (pg backends):

SELECT cron.Register('cron.Example_No_Sleep(integer)', _Processes := 2);

Don't limit how many cron job functions that can be running in parallell (DEFAULT):

SELECT cron.Register('cron.Example_No_Sleep(integer)', _ConnectionPool := NULL);

Create a connection pool to limit the number of concurrently running processes:

SELECT cron.New_Connection_Pool(_Name := 'My test pool', _MaxProcesses := 2);

Create a connection pool to limit the number of concurrently running processes:

SELECT cron.Register('cron.Example_No_Sleep(integer)', _ConnectionPool := 'My test pool');

Run until cron job returns DONE, then never run again (DEFAULT):

SELECT cron.Register('cron.Example_No_Sleep(integer)', _IntervalDONE := NULL);

Run until cron job returns DONE, then run again after 60 seconds:

SELECT cron.Register('cron.Example_No_Sleep(integer)', _IntervalDONE := '60 seconds'::interval);

The two examples below uses pg_catalog.pg_stat_activity.waiting or pg_catalog.pg_stat_activity.wait_event depending on the PostgreSQL version.

Don't run cron job if any other PostgreSQL backend processes are waiting (DEFAULT):

SELECT cron.Register('cron.Example_Update_Same_Row(integer)', _RunIfWaiting := FALSE);

Run cron job even if there are other PostgreSQL backend processes waiting:

SELECT cron.Register('cron.Example_Update_Same_Row(integer)', _RunIfWaiting := TRUE);

Run at specific timestamp and then forever:

SELECT cron.Register('cron.Example_Random_Sleep(integer)', _RunIfWaiting := TRUE, _RunAfterTimestamp := now()+'10 seconds'::interval);

Run immediately from now until a specific timestamp in the future:

SELECT cron.Register('cron.Example_Random_Sleep(integer)', _RunIfWaiting := TRUE, _RunUntilTimestamp := now()+'15 seconds'::interval);

Run between two specific timestamps:

SELECT cron.Register('cron.Example_Random_Sleep(integer)', _RunIfWaiting := TRUE, _RunAfterTimestamp := now()+'20 seconds'::interval, _RunUntilTimestamp := now()+'25 seconds'::interval);

Run after a specific time of day and then forever:

SELECT cron.Register('cron.Example_Random_Sleep(integer)', _RunIfWaiting := TRUE, _RunAfterTime := now()::time+'30 seconds'::interval);

Run immediately from now until a specific time of day:

SELECT cron.Register('cron.Example_Random_Sleep(integer)', _RunIfWaiting := TRUE, _RunUntilTime := now()::time+'35 seconds'::interval);

Run between two specific time of day values:

SELECT cron.Register('cron.Example_Random_Sleep(integer)', _RunIfWaiting := TRUE, _RunAfterTime := now()::time+'40 seconds'::interval, _RunUntilTime := now()::time+'45 seconds'::interval);


Useful to e.g. split large updates into multiple smaller db txns and sleep in between, or to run slow queries during non-peak hours.







No releases published


No packages published