Installation
Install the package, run the migration, and start a worker.
Requirements
- Postgres 13 or newer
- Node.js 20 or newer
Postgres 13 is the floor because Halyard uses SKIP LOCKED, which is
available earlier, and gen_random_uuid() from pgcrypto, which became
built-in in 13.
Install
npm install halyard
Run the migration
Halyard ships its schema as a single idempotent migration. Run it once per database:
npx halyard migrate --database-url "$DATABASE_URL"
This creates one table (halyard_jobs) and two indexes. It does not create a
schema, a role, or an extension — if your database policy requires those to be
managed elsewhere, the SQL is printed with --dry-run so you can hand it to
whoever owns migrations.
npx halyard migrate --dry-run
Define a job
import { defineJob } from "halyard";
export const sendReceipt = defineJob({
name: "send-receipt",
async handler({ orderId }: { orderId: string }) {
const order = await orders.find(orderId);
await mailer.send(order.email, receiptTemplate(order));
},
});
The name is the durable identifier stored in the database. Changing it
orphans any queued jobs using the old name, so treat it like a table name
rather than a variable.
Start a worker
import { createWorker } from "halyard";
import { sendReceipt } from "./jobs/send-receipt";
const worker = createWorker({
connectionString: process.env.DATABASE_URL,
jobs: [sendReceipt],
concurrency: 10,
});
await worker.start();
Run this as a separate process from your web server. It can be the same container image with a different command.
Verify
npx halyard status --database-url "$DATABASE_URL"
queued 0
running 0
failed 0
workers 1 (last heartbeat 2s ago)
If workers is 0, the worker process is not running or cannot reach the
database.