Schedule recurring SQL commands inside PostgreSQL with extensions like pg_cron, eliminating external cron scripts.
Install the pg_cron extension, load it in the desired database, then use the cron.schedule function to register a job that runs on a crontab-style timetable.
Add pg_cron to shared_preload_libraries in postgresql.conf, restart the server, then run CREATE EXTENSION pg_cron;
in the database that will own the jobs.
You call SELECT cron.schedule(job_name, schedule, command);
where schedule
is a five-field crontab string and command
is the SQL you want executed.
Query cron.job
to view jobs.Modify timing or SQL with cron.alter_job(job_id, schedule, command)
. Remove jobs with cron.unschedule(job_id)
.
Yes. Inside postgresql.conf
set cron.database_name
and cron.job_owner
defaults.Alternatively, provide run_as
and database
arguments in cron.schedule
.
Batch tasks such as refreshing materialized views or archiving old orders at low-traffic times (e.g., 02:00) to avoid user-facing latency spikes.
Name jobs with a clear prefix like daily_
or hourly_
so they sort naturally and self-document in cron.job
.
Use cron.schedule('daily_sales_summary', '5 1 * * *', $$REFRESH MATERIALIZED VIEW CONCURRENTLY daily_sales_summary$$);
.The job runs every day at 01:05.
Set schedule to '*/15 * * * *'
. Example: cron.schedule('quarter_hour_inventory', '*/15 * * * *', $$CALL update_product_stock()$$);
.
Check cron.job_run_details
for exit_code and stderr. Wrap SQL in DO blocks with explicit RAISE NOTICE statements to surface intermediate values during failures.
.
pg_cron is available on Amazon RDS for PostgreSQL 13+ and Aurora PostgreSQL. Enable it in the DB parameter group, then create the extension in each database.
Installing the extension needs superuser rights or rds_superuser on RDS. Once installed, non-superusers can schedule jobs if allowed by the cron.job_owner setting.
pg_cron checks schedules once per minute. Jobs usually start within a few seconds of the specified minute.