# What is Workhorse?

> A durable job queue that lives inside PostgreSQL, so your jobs commit with your data.

Every application eventually needs work that outlives a request: send the email, charge the card,
rebuild the report. The moment that work moves to a separate broker, you have two systems that can
disagree — an order row without its job, or a job for an order that rolled back.

Workhorse removes the second system. It is a durable job queue built from PostgreSQL tables and
versioned SQL functions, with supported SDKs for TypeScript, Python, and Go. There is no broker, no
Redis, and no PostgreSQL extension — one database owns your business data, your queued work, your
execution state, and the evidence of what happened.

## The core promise

`Queue.enqueue` accepts your open transaction as its last argument. If the transaction commits, the
job exists; if it rolls back, PostgreSQL removes the business write and the job together.

```ts
import { Pool, Queue } from "@stablemates/workhorse";

const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const queue = new Queue(pool);

const client = await pool.connect();
try {
  await client.query("BEGIN");
  await client.query("INSERT INTO orders (id) VALUES ($1)", [orderId]);
  await queue.enqueue("order.fulfill", { orderId }, {}, client);
  await client.query("COMMIT");
} finally {
  client.release();
}
```

A `Worker` claims the job and runs the handler you registered with `Worker.handle`. Each claim
grants a temporary lease and a fence token. If the worker dies, the lease expires, another worker
recovers the job, and the fence token blocks the dead worker from writing stale results.

Handlers run outside database transactions, so delivery is at least once: a handler can run twice
after a crash. Named checkpoints make that safe. If a handler restarts, `ctx.checkpoint` replays
each completed stage's stored result instead of running it again.

```ts
import { Worker } from "@stablemates/workhorse";

const worker = new Worker(queue).handle("order.fulfill", async (payload, ctx) => {
  const charge = await ctx.checkpoint("charge", () => chargeCard(payload.orderId));
  // If the process dies here, the retry skips "charge" and resumes below.
  const label = await ctx.checkpoint("label", () => printLabel(payload.orderId));
  return { chargeId: charge.chargeId, labelId: label.labelId };
});
await worker.run();
```

Beyond checkpoints, jobs get retries with configurable backoff, durable sleeps that release the
worker slot, cron-style schedules, idempotent enqueue, dead letters with redrive, and immutable
history you can query with `Admin.getJob` and `Admin.getJobTimeline`.

## When to use it

If your application already runs on PostgreSQL and needs reliable background work, Workhorse fits.
Choose its TypeScript, Python, or Go SDK and connect it to PostgreSQL 15 or newer.

Workhorse is a public beta. It is usable for evaluation and early production adoption, but any
minor release may break compatibility, including the schema. There is no upgrade path between 0.x
releases; ordered migrations begin at 1.0.0.

Workhorse supports strict priority, dependency fan-in, child jobs, external signals, and human
decisions. Orchestration remains application code rather than a separate workflow definition.
External calls still need provider idempotency keys. If the queue must scale independently of the
database, use a dedicated broker.

## Which package do I need?

- `@stablemates/workhorse` provides `Queue`, `Admin`, `Worker`, schema tools, process orchestration, and the CLI.
- `stablemates-workhorse` provides synchronous and asynchronous Python queue clients and workers.
- `github.com/stablemates/workhorse/go` provides Go queue clients and workers over pgx or `database/sql`.
- `@stablemates/workhorse-dashboard` provides the operator interface and its framework-neutral server host.
- `@stablemates/workhorse-drizzle` adapts Drizzle databases and transactions to the core `Queryable` protocol.
- `@stablemates/workhorse-prisma` adapts Prisma clients and interactive transactions.
- `@stablemates/workhorse-typeorm` adapts TypeORM data sources and transactional entity managers.
- `@stablemates/workhorse-kysely` adapts Kysely databases and transactions.

TypeScript applications start with `@stablemates/workhorse`, which includes its default PostgreSQL
driver. Python includes Psycopg by default and offers an asyncpg extra, while Go includes pgx.
TypeScript applications add an adapter when they want to enqueue inside an ORM transaction.

## Next

- [Installation](/docs/installation) — add the package and install its schema
- [Quickstart](/docs/quickstart) — run a job, kill the worker, watch it finish anyway
- [Core concepts](/docs/concepts) — states, ownership, and why a handler can run twice

---

Exact lifecycle guarantees, tables, and protocol boundaries:
[architecture reference](https://github.com/stablemates/workhorse/blob/main/docs/architecture.md#design-objective).
