Scheduling cron jobs with pg_cron and pg_net
Use native Postgres scheduling and HTTP calls to automate workflows without extra servers.
Running background jobs directly in Postgres is surprisingly effective for many workloads. pg_cron schedules SQL at the database level, and pg_net can call HTTP endpoints from inside Postgres. Together they let you automate tasks without a separate worker.
Install the extensions
CREATE EXTENSION IF NOT EXISTS pg_cron;
CREATE EXTENSION IF NOT EXISTS pg_net;
Make sure pg_cron is configured with the right database in postgresql.conf.
Example: nightly cleanup
SELECT cron.schedule(
'nightly_cleanup',
'0 2 * * *',
$$DELETE FROM audit_logs WHERE created_at < now() - interval '90 days'$$
);
Example: ping a webhook
SELECT net.http_post(
url := 'https://example.com/webhooks/daily-rollup',
headers := '{"Authorization": "Bearer token"}'::jsonb,
body := '{"source":"pg_cron"}'::jsonb
);
Observability tips
- Store
cron.job_run_detailsin a dashboard table. - Add a short retention policy for old runs.
- Emit alerts for consecutive failures.
When to use this pattern
If your task is data-local and short-lived, pg_cron is a clean fit. For long-running or CPU-heavy jobs, keep a separate worker process.
About the author
Okechukwu Samuel Owhondah
Frontend and full-stack software engineer building scalable, user-focused web applications with React, Next.js, TypeScript, and Python-based backends.
Discussion
Questions, corrections, and thoughtful additions are welcome.