API overview
The public surface grouped by concern — Queue, Admin, Worker, HandlerContext, errors, schema tools, and the CLI.
Workhorse's public surface is small: Queue produces and controls application work, Admin
provides operator reads and controls, and Worker runs jobs. A handful of schema and process helpers surround them. This page
maps that surface by concern so you can find the right method fast. It is an overview, not an
exhaustive reference — the published TypeScript declarations carry the exact signatures, and
typescript/core/src/index.ts is the
authoritative export list.
Queue
new Queue(database, defaultQueue?, options?) takes any Queryable — a pg pool, a client, or an ORM adapter.
Producing work. enqueue(type, payload, options?, transaction?) accepts one job and returns
its ID; pass an open transaction as the last argument to commit the job with your data.
enqueueMany(requests, transaction?) accepts a bounded batch. enqueueWithResult and
enqueueManyWithResults return each retained job ID with an EnqueueOutcome describing whether
PostgreSQL accepted, replayed, replaced, could not replace, or coalesced the request.
EnqueueOptions carries
queue, runAt, priority, deadline, executionTimeoutMs, maxAttempts, retryPolicy,
concurrencyKey, tags, idempotency, debounce, throttle, and dependency inputs.
Stopping work. cancel(jobId, { requestedBy, reason }) records an attributed cooperative
cancellation. Queued work cancels immediately; active handlers observe it through their
AbortSignal.
Recurring work. syncSchedules(namespace, definitions, options?) reconciles a namespace of
cron definitions during deployment. fireSchedule exposes the revision-fenced firing operation.
Deployment-synchronized policies. syncConcurrencyPolicies, syncRateLimitPolicies,
syncRetentionPolicy, and syncMaintenancePolicy write desired state; each has a matching read —
concurrencyPolicies, rateLimitPolicies and rateLimitStatuses, getRetentionPolicy, and
getMaintenancePolicy. Retention adds overrideRetentionPolicy, revertRetentionPolicy, and
previewRetentionPolicy for operator changes with provenance.
Go exposes concurrency and rate-limit desired state through Queue.SyncConcurrencyPolicies and
Queue.SyncRateLimitPolicies. Queue.ListConcurrencyPolicies and Queue.ListRateLimitPolicies
return the persisted typed policies through the same caller-owned executor.
Python exposes the same boundary through synchronous and asynchronous
sync_concurrency_policies, sync_rate_limit_policies, list_concurrency_policies, and
list_rate_limit_policies methods. They use the caller-owned Psycopg or asyncpg transaction.
External waits and child work. sendSignal and completeHumanWait deliver an attributed, idempotent result after the caller
enforces authorization. Workers use the
lower-level scheduleWait, waitForSignal, waitForHuman, createChild, and createChildren
methods under a claimed job's fence; application code normally reaches those through
HandlerContext.
Health. health() returns a database-evaluated QueueHealth verdict with reasons.
queueMetricSnapshot() feeds metrics exporters.
Maintenance. Workers normally drive maintenance for you. The underlying operations —
promote, recoverExpired, tick, rollupStatistics, prepareHistoryPartitions,
retainHistory, and pruneTerminalStorage — are public for controlled setups and tests.
Admin
new Admin(database, defaultQueue?, options?) accepts the same Queryable and configuration as
Queue, but exposes the operator boundary.
Go exposes the matching boundary through workhorse.NewAdmin(executor). It uses the same pgx or
database/sql executor as NewQueue, while the caller retains connection and transaction ownership.
Reading evidence. getJob, listJobs, and getJobTimeline inspect jobs.
listCheckpoints, listWaits, listSignalWaits, listHumanWaits, and getProgress inspect
durable boundaries. Dependency, child, and redrive lineage reads expose retained graph edges.
Failure and fleet controls. listDeadLetters, redrive, and redriveMany inspect and replay
terminal failures. listWorkers and setWorkerPaused inspect and steer worker processes.
pauseQueue, resumeQueue, and purgeQueue control a whole queue. Every mutation takes
{ actor, reason, requestId }; purge returns its deleted count and safely replays the same request.
schedules reads recurring definitions, and runTaskNow releases one scheduled job early.
Worker
new Worker(queue, options?) claims and runs jobs with bounded concurrency.
handle(type, handler)registers a typed handler and returns the worker for chaining.handleBatch(type, options, handler)groups jobs of one type while preserving a separate outcome and fence for every member.run(signal?)is the production loop;runOnce()performs one claim-and-run pass.stop()drains: no new claims, active handlers finish.pause()andresume()toggle claiming locally;runtimeState()andmaintenanceTelemetry()expose what the worker is doing.
WorkerOptions covers identity and capacity (queue, workerId, concurrency), ownership timing
(leaseMs, heartbeatMs, pollMs), maintenance polling (maintenanceIntervalMs,
maintenanceTaskPollMs, registryIntervalMs), schedule evaluation (scheduleNamespaces,
scheduleCatchupLimit), retry shaping (retryDelayMs), and error callbacks
(onRegistrationError, onNotificationError, onMaintenance).
HandlerContext
Every handler receives (payload, context). The context is the durable-execution surface:
job— theClaimedJobwith ID, attempt, and metadata.signal— anAbortSignalaborted on cancellation, deadline, or execution timeout.checkpoint(name, operation)— run once, persist the JSON result, replay it on restart.sleep(name, durationMs)andsleepUntil(name, wakeAt)— durable timers that release the worker slot without consuming the attempt.waitForSignal(name, options?)andwaitForHuman(name, context, options?)— external boundaries that restart the handler after an application or operator supplies a result.runChild(name, type, payload, options?)andrunChildren(children)— delegate durable work, release the parent slot, and join tagged terminal outcomes.runChildrenAll(children)— require every child to succeed and propagate a rejected outcome.setProgress(value)andgetProgress()— mutable operator-visible status.getCheckpoint(name)andgetWait(name)— read one durable boundary without executing code.
Errors
All Workhorse errors extend WorkhorseError. The ones you are most likely to catch:
EnqueueIdempotencyConflictErrorandRedriveIdempotencyConflictError— a replay differed materially from the original request.CheckpointConflictErrorandWaitConflictError— a durable name was reused with different content;WaitLimitExceededErrorbounds waits per job.ChildConflictError,ChildLimitExceededError, andChildResultLimitExceededError— child work changed during replay or exceeded a bounded set or result.DependencyCycleErrorandDependencyLimitExceededError— a dependency would create a cycle or unbounded graph work.CheckpointLeaseLostError,ProgressLeaseLostError, andWaitLeaseLostError— a stale worker tried to write after losing ownership.CancellationRequestedError,DeadlineExceededError, andExecutionTimeoutError— the reasons behind an abortedcontext.signal.JobContractValidationError,JobContractUnavailableError, andJobValueSizeLimitError— payload contract and size enforcement.
Exported constants such as MAX_ENQUEUE_BATCH_SIZE, MAX_CHECKPOINT_VALUE_BYTES, and
MAX_REDRIVE_BATCH_SIZE expose every operational limit to tooling.
Schema and support
installSchema(database)installs the full schema; run it as a deployment step.assertSchemaCompatible(database)fails startup on a runtime/schema mismatch;readSchemaVersionandWORKHORSE_SCHEMA_VERSIONexpose both sides of that check.protocol/v1/publishes language-neutral fixtures for canonical enqueue requests, worker transitions, result shapes, and SQLSTATE-backed structured errors.assertSupportedPostgres,readPostgresSupport, anddescribePostgresSupportclassify the connected server;MINIMUM_NODE_MAJOR,MINIMUM_POSTGRES_MAJOR,SUPPORTED_NODE_MAJORS, andSUPPORTED_POSTGRES_MAJORSpublish the tested boundary.
Worker processes and adapters
defineWorkerProcess(definition)describes an owned runtime — adapter, workers, probes.startWorkerProcessstarts it under your control;runWorkerProcessadds the standalone Node.js lifecycle with signal handling and bounded drain.createWorkhorseAdapterbuilds aWorkhorseAdapterfrom anyQueryable; the Drizzle, Prisma, TypeORM, and Kysely packages wrap it for their ORMs.
CLI
The workhorse CLI covers setup and operations without writing code:
npx workhorse init # scaffold config and wiring
npx workhorse schema install # install the schema
npx workhorse schema status --json # report schema and PostgreSQL status
npx workhorse worker --config workhorse.config.js # run a supervised worker process
npx workhorse dashboard --port 3000 # serve the operator dashboard
npx workhorse health --json # emit machine-readable queue health
npx workhorse bench # run the isolated benchmark suite
npx workhorse bench competitors # run competitor baselinesThe package exposes only the workhorse binary. Each command rejects unknown options and accepts
both --flag value and --flag=value. Run workhorse <command> --help for its options.
Next
- Enqueue and transactions — producer behavior in depth
- Workers — handler behavior in depth
- Queries and timelines — operator reads in depth
Exact protocol functions, fields, constants, and operational limits: architecture reference.