@stablemates/workhorse
v0.8.0
Published
A durable task queue for PostgreSQL. Public beta.
Readme
@stablemates/workhorse
The TypeScript client, worker runtime, schema tools, and operator API for the Workhorse durable task queue for PostgreSQL.
Public beta: Workhorse is usable for evaluation and early production adoption. A 0.x minor release may change behaviour, so read the changelog before you upgrade. It will not ask you to recreate your database: migrations are ordered, and inside a major line a migration only adds, so a running deployment upgrades in place.
An AI agent should read the Workhorse documentation index first.
Install
npm install @stablemates/workhorse
npm exec --no -- workhorse schema installInstall the schema during deployment. Runtime processes should verify compatibility instead of
attempting schema changes. npm exec --no runs the binary this project already depends on, so the
schema tool and the application always agree on a version.
Requires Node.js 22 or 24 and PostgreSQL 15 through 18.
Run one task
import { Admin, Pool, Queue, Worker } from "@stablemates/workhorse";
export async function runQuickstart(databaseUrl: string) {
const pool = new Pool({ connectionString: databaseUrl });
try {
const queue = new Queue(pool);
const admin = new Admin(pool);
const worker = new Worker(queue, { workerId: "quickstart-worker" }).handle<{ name: string }>(
"welcome.send",
async (payload) => ({ message: `Welcome, ${payload.name}!` }),
);
const taskId = await queue.enqueue("welcome.send", { name: "Ada" });
await worker.runOnce();
const task = await admin.getTask(taskId);
if (task?.state !== "succeeded") throw new Error(`Quickstart task finished in ${task?.state}`);
return { taskId, result: task.result };
} finally {
await pool.end();
}
}Handlers receive at-least-once delivery. Use stable provider idempotency keys around external effects; named checkpoints prevent completed application stages from running after a later restart.
Task groups, checkpoint inputs, and single passes
- A task group tracks many tasks as one unit. After the
group is sealed and every member task is finished, Workhorse enqueues the callback tasks of the
group.
queue.taskGroupcreates a group, adds its tasks, and seals it in one transaction. - A handler can give the input of a
checkpoint. Give it
as
ctx.checkpoint(name, operation, { input }). If a later run gives a different input, the call raisesCheckpointInputConflictError, the task fails, and the operation does not run again. If the stored checkpoint or the call has no input, Workhorse compares nothing. worker.runOnce()returns true only when a handler ran. It returns false after a pass that only released the tasks that it claimed. If you call it in a loop, wait after false.
Package boundary
This package owns the PostgreSQL schema, protocol client, worker runtime, CLI, and operator API. Run
schema changes as a deployment step; application and worker processes should only check compatibility.
ORM applications can add a provider package to enqueue through an existing application transaction.
Core has no telemetry vendor dependency. Applications that use OpenTelemetry install
@stablemates/workhorse-otel, configure their global SDK providers, and call
registerOpenTelemetry() during process startup.
Next
- Follow the quickstart and deploy worker processes.
- Read the API reference, CLI guide, and compatibility policy.
- Use the operations guide for health, retention, and maintenance.
- Browse the repository or report a problem in GitHub issues.
License
Apache-2.0. See LICENSE and NOTICE in the package.
