pg_cron is a PostgreSQL extension that lets you schedule SQL statements to run automatically at specified times or intervals, using standard cron syntax. All scheduling is managed through SQL functions — no external scripts or configuration files required.
Prerequisites
Before you begin, make sure that your cluster meets the following version requirements:
PolarDB for PostgreSQL (Compatible with Oracle) 2.0 — revision version 2.0.14.1.0 or later
PolarDB for PostgreSQL (Compatible with Oracle) 1.0 — revision version 1.1.1 or later
To check the revision version of your cluster, run:
SHOW polar_version;Usage notes
If you restart a cluster running minor engine version 2.0.14.16.0 or earlier, the cluster port changes and existing pg_cron scheduled tasks may fail. This issue is fixed in minor engine version 2.0.14.16.1 and later.
How it works
Scheduled task information maintenance
All scheduled tasks are stored in the cron.job table. When the database starts, pg_cron builds two internal lists — JOB LIST and TASK LIST — from the cron.job table. The cron.job_cache_invalidate trigger keeps these lists in sync with cron.job in real time whenever tasks are added, modified, or deleted.
Scheduled task execution
Each scheduled task moves through the following states:
| State | Description |
|---|---|
| WAITING | Default state. The scheduler skips the task if conditions are not met (task inactive or scheduled time not reached). When conditions are met, the task moves to START. |
| START | Establishes connection information and runs a connection test. Moves to CONNECTING on success, or ERROR on failure. |
| CONNECTING | Checks whether the task is active and the connection is valid. Moves to SENDING on success, or ERROR on failure. |
| SENDING | Sends the task to the PolarDB for PostgreSQL (Compatible with Oracle) server. Moves to RUNNING on success, or ERROR on failure. |
| RUNNING | Receives the task result. Moves to DONE on success, or ERROR if the connection drops. |
| ERROR | Task failed. Resets connection information and moves to DONE. |
| DONE | Task complete. Resets task information and returns to WAITING. |
Functions
Only privileged accounts can call the following functions to create or modify entries incron.job. Standard accounts have read-only access tocron.job.
All scheduled tasks are stored in the postgres database. Connect to postgres to manage your scheduled tasks.
Scheduled tasks run on Greenwich Mean Time (GMT). Convert your local time to GMT before setting a schedule.
cron.schedule
Creates a scheduled task.
cron.schedule(
job_name TEXT,
schedule TEXT,
command TEXT
)| Parameter | Description |
|---|---|
job_name | Name of the task. Optional — leave blank to omit. |
schedule | Schedule in standard cron expression format. |
command | SQL statement to run. |
cron.schedule_in_database
Creates a scheduled task in a specified database.
cron.schedule_in_database(
job_name TEXT,
schedule TEXT,
command TEXT,
db_name TEXT
)| Parameter | Description |
|---|---|
job_name | Name of the task. |
schedule | Schedule in standard cron expression format. |
command | SQL statement to run. |
db_name | Database where the task runs. |
cron.alter_job
Modifies an existing scheduled task. Pass NULL for any parameter you do not want to change.
cron.alter_job(
job_id BIGINT,
schedule TEXT DEFAULT NULL,
command TEXT DEFAULT NULL,
db_name TEXT DEFAULT NULL,
active BOOLEAN DEFAULT NULL
)| Parameter | Description |
|---|---|
job_id | ID of the task to modify. |
schedule | New cron expression. |
command | New SQL statement. |
db_name | Database where the task will run after modification. |
active | true to activate the task; false to deactivate it. |
cron.unschedule
Deletes a scheduled task by ID or name.
cron.unschedule(job_id BIGINT);
cron.unschedule(job_name TEXT);| Parameter | Description |
|---|---|
job_id | ID of the task to delete. |
job_name | Name of the task to delete. |
Manage scheduled tasks
The following operations require a privileged account.
Create the pg_cron extension
Connect to the database and run:
CREATE EXTENSION pg_cron;Create a scheduled task
The following example creates a task named task1 that runs SELECT 1 every minute in the db01 database. The function returns the task ID.
SELECT cron.schedule_in_database('task1', '* * * * *', 'SELECT 1', 'db01');Output:
schedule_in_database
----------------------
1
(1 row)View scheduled tasks
SELECT * FROM cron.job;Output:
jobid | schedule | command | nodename | nodeport | database | username | active | jobname
-------+-----------+----------+----------+----------+----------+----------+--------+---------
1 | * * * * * | SELECT 1 | /tmp | 39361 | db01 | u1 | t | task1
(1 row)View task execution history
To view all execution records:
SELECT * FROM cron.job_run_details;Output:
jobid | runid | job_pid | database | username | command | status | return_message | start_time | end_time
-------+-------+---------+----------+----------+----------+-----------+----------------+-------------------------------+-------------------------------
1 | 1 | 4152316 | db01 | u1 | SELECT 1 | succeeded | 1 row | 2023-10-19 03:55:00.020442+00 | 2023-10-19 03:55:00.021512+00
1 | 2 | 4152438 | db01 | u1 | SELECT 1 | succeeded | 1 row | 2023-10-19 03:56:00.006468+00 | 2023-10-19 03:56:00.006822+00
(2 rows)To view only failed runs:
SELECT * FROM cron.job_run_details WHERE status = 'failed';Delete a scheduled task
SELECT cron.unschedule('task1');Output:
unschedule
------------
t
(1 row)Delete the pg_cron extension
DROP EXTENSION pg_cron;Cron syntax reference
pg_cron uses standard cron syntax:
┌───────────── Minute (0–59)
│ ┌────────────── Hour (0–23)
│ │ ┌─────────────── Day of month (1–31)
│ │ │ ┌──────────────── Month (1–12)
│ │ │ │ ┌───────────────── Day of week (0–6, where 0 and 7 = Sunday)
│ │ │ │ │
* * * * *Special characters
| Character | Meaning | Example |
|---|---|---|
* | Every value in the field | * * * * * — every minute |
, | List of specific values | 1,3,5 in day-of-week — Monday, Wednesday, Friday |
- | Range of values | 10-12 in hour — hours 10, 11, and 12 |
/ | Step values | */15 in minute — every 15 minutes |
Schedule examples
The following examples cover common DBA tasks. All times are in GMT.
Delete expired data every Saturday at 03:30:
SELECT cron.schedule('30 3 * * 6', $$DELETE FROM events WHERE event_time < now() - interval '1 week'$$);Run a job every day at 10:00:
SELECT cron.schedule('0 10 * * *', 'VACUUM;');Run a job every minute:
SELECT cron.schedule('* * * * *', 'SELECT 1;');Run a job at minute 23 of every hour:
SELECT cron.schedule('23 * * * *', 'SELECT 1;');Run a job on the fourth day of each month:
SELECT cron.schedule('* * 4 * *', 'SELECT 1;');