Back to Blog
Tutorial9 min read2026-06-29

How to Deploy Graphile Worker for Postgres-Backed Jobs

Skip Redis entirely: Graphile Worker runs a fast job queue inside your existing PostgreSQL. Here's how to deploy it, define tasks, schedule crontab jobs, and keep it healthy.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Graphile Worker is a high-performance job queue for Node.js that uses PostgreSQL as its only dependency. No Redis, no RabbitMQ — jobs live in your existing database and are picked up using LISTEN/NOTIFY plus SKIP LOCKED for low-latency, contention-free dequeuing. If you already run Postgres and don't want another stateful service to operate, this is a compelling choice.

Why Postgres-only is attractive

Every additional broker is another thing to provision, secure, back up, and monitor. Graphile Worker folds the queue into the database you already have, so a job and the data it mutates can even share a transaction — enqueue a job atomically with the database change that triggered it, eliminating the classic "committed the row but lost the job" race.

PropertyGraphile WorkerRedis-based queues
Extra infranone (uses Postgres)a broker
Transactional enqueueyesno
Latencyvery low (LISTEN/NOTIFY)very low
Throughput ceilingbounded by Postgresvery high

The honest tradeoff: at extreme job volumes a dedicated broker scales further, but most applications never approach that ceiling.

Defining tasks

Tasks are plain async functions in a tasks/ directory, named by file:

// tasks/send_email.js
module.exports = async (payload, helpers) => {
  const { email } = payload
  helpers.logger.info(`sending to ${email}`)
  // ... do the work
}

Enqueue from your app, ideally inside the same transaction as the related write:

await addJob('send_email', { email: user.email })

Deploying the worker

Graphile Worker runs as a standalone process or embedded in your app. For production, run it as its own service so background load is isolated from your web tier:

npx graphile-worker -c "$DATABASE_URL"

First run installs its schema (graphile_worker) into the database. On PandaStack, attach a managed PostgreSQL to both your web service and the worker service; the injected DATABASE_URL is all Graphile Worker needs. The worker requires no public port.

Concurrency and connection budget

Control parallelism with --jobs (the number of jobs run concurrently) and size the pool accordingly. Because the worker holds Postgres connections, keep an eye on your database's connection limit — web app + worker concurrency + replicas all share it. On smaller tiers, set --jobs modestly and scale worker replicas only as needed.

npx graphile-worker -c "$DATABASE_URL" --jobs 5

Scheduled jobs with crontab

Graphile Worker has a built-in crontab for recurring jobs — define them in a crontab file:

# m h dom mon dow  task
0 3 * * *           nightly_cleanup
*/15 * * * *        refresh_cache

This runs inside the worker process, so there's no separate scheduler to keep singleton. For very simple schedules you could instead use a platform cronjob to invoke a script, but Graphile Worker's crontab keeps everything in one place with backfill semantics.

Retries and failure

Failed jobs are retried with exponential backoff automatically. Tune maxAttempts per task. Jobs that exhaust retries remain in the table for inspection — query graphile_worker.jobs to see stuck or failing work. Because it's just SQL, your existing database tooling and dashboards work for monitoring the queue.

Go-live checklist

  • Worker deployed as its own service from the same repo
  • Managed Postgres attached; DATABASE_URL shared
  • --jobs sized to workload and connection budget
  • Transactional addJob where correctness matters
  • crontab file for recurring jobs
  • Monitor graphile_worker.jobs for failures

References

  • [Graphile Worker documentation](https://worker.graphile.org/)
  • [Graphile Worker on GitHub](https://github.com/graphile/worker)
  • [Graphile Worker cron](https://worker.graphile.org/docs/cron)
  • [PostgreSQL SKIP LOCKED](https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE)

Graphile Worker is a perfect match for PandaStack's auto-wired databases: attach one managed PostgreSQL, run the worker as a second service, and you have a transactional job queue with zero extra infrastructure. Start free at [dashboard.pandastack.io](https://dashboard.pandastack.io).

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also