Skip to main content

Creating a worker

Call hatchet.worker(name, options?) to create and initialize a worker. This is an async operation that registers the worker’s workflows with the Hatchet server.
worker.ts
import { hatchet } from './hatchet-client';
import { simple } from './workflow';

async function main() {
  const worker = await hatchet.worker('simple-worker', {
    workflows: [simple],
    slots: 100,
  });

  await worker.start();
}

main();

Signature

hatchet.worker(name: string, options?: CreateWorkerOpts): Promise<Worker>
name
string
required
The name of the worker, visible in the Hatchet dashboard.
options
CreateWorkerOpts
Configuration options. See Worker options below.

Worker options

workflows
Array<WorkflowDeclaration | TaskWorkflowDeclaration>
The list of workflows (and standalone tasks) the worker can execute. Workflows can also be registered after construction via worker.registerWorkflows().
slots
number
default:"100"
Maximum number of concurrent standard task runs this worker will accept.
durableSlots
number
default:"1000"
Maximum number of concurrent durable task runs this worker will accept.
labels
WorkerLabels
Key-value labels attached to this worker for affinity-based task routing. Values can be string or number.
handleKill
boolean
When true, the worker registers signal handlers for SIGTERM and SIGINT to gracefully shut down.

Registering workflows

You can pass workflows directly in the constructor options or register them after the worker is created:
const worker = await hatchet.worker('my-worker');

// Register multiple workflows at once
await worker.registerWorkflows([workflowA, workflowB]);

// Register a single workflow
await worker.registerWorkflow(workflowC);
Register all workflows before calling worker.start(). Workflows registered after the worker has started will not be picked up by the current session.

Starting the worker

Call worker.start() to connect to Hatchet and begin processing tasks. This returns a promise that resolves when the worker stops:
async function main() {
  const worker = await hatchet.worker('my-worker', {
    workflows: [myTask],
  });

  // Blocks until the worker is stopped
  await worker.start();
}
To wait until the worker has successfully registered before proceeding (useful in tests or scripts), use worker.waitUntilReady():
const workerPromise = worker.start();
await worker.waitUntilReady(); // Polls until registered

// Worker is now ready — safe to trigger tasks
const result = await myTask.run({ Message: 'hello' });

await workerPromise;

Stopping the worker

worker.stop();
This signals the worker to stop accepting new tasks and complete any in-flight runs before disconnecting.

Worker labels

Labels allow you to route specific tasks to specific workers. Define labels when creating the worker and reference them in task desiredWorkerLabels:
affinity-workers.ts
import { WorkerLabelComparator } from '@hatchet-dev/typescript-sdk';
import { hatchet } from './hatchet-client';

// Worker with labels
const worker = await hatchet.worker('gpu-worker', {
  labels: {
    model: 'xyz',
    memory: 512,
  },
  workflows: [myWorkflow],
});

// Task that requires a specific label
myWorkflow.task({
  name: 'gpu-step',
  desiredWorkerLabels: {
    model: {
      value: 'xyz',
      required: true,
    },
    memory: {
      value: 512,
      required: true,
      comparator: WorkerLabelComparator.LESS_THAN,
    },
  },
  fn: async (input) => {
    // Runs only on workers where model='xyz' and memory<=512
    return { result: 'done' };
  },
});

await worker.start();

Updating labels at runtime

Labels can be updated while the worker is running:
await worker.upsertLabels({
  model: 'abc',
  memory: 1024,
});

// Read the current labels
const labels = worker.getLabels();

Pausing and unpausing

Pause a worker to stop it from accepting new tasks without stopping the process:
await worker.pause();
console.log(await worker.isPaused()); // true

await worker.unpause();
console.log(await worker.isPaused()); // false

Full example

worker.ts
import { hatchet } from './hatchet-client';
import { simple } from './workflow';
import { parent, child } from './workflow-with-child';

async function main() {
  const worker = await hatchet.worker('simple-worker', {
    // Declare all workflows the worker can execute
    workflows: [simple, parent, child],
    // Maximum concurrent task runs
    slots: 100,
  });

  await worker.start();
}

if (require.main === module) {
  main();
}

Build docs developers (and LLMs) love