Aiki
Core Concepts

Workers

A worker executes your workflows. It runs in your infrastructure, subscribes to workflow run messages, and executes the workflow logic you've defined. You can run multiple workers to scale horizontally—they automatically share the workload.

Creating a Worker

import { client } from "@aikirun/client";
import { worker } from "@aikirun/worker";
import { orderWorkflowV1, userWorkflowV1 } from "./workflows";

const aikiClient = client({
  url: "http://localhost:9850",
  apiKey: "your-api-key",
});

const aikiWorker = worker({
  workflows: [orderWorkflowV1, userWorkflowV1],
  options: {
    maxConcurrentWorkflowRuns: 10,
  },
});

const handle = aikiWorker.spawn(aikiClient);

Worker definitions are static and reusable. The worker() function creates a definition with a workflows array specifying which workflow versions it can execute. Call spawn(client) to begin execution; it returns a handle for controlling the running worker.

How Workers Operate

When you call spawn(), the worker begins discovering ready workflow runs through its subscriber — claiming them from the server by default. When a workflow run is triggered, the worker picks it up, looks up the workflow definition in its registry, and begins execution.

During execution, the worker sends periodic heartbeats to maintain its claim on the run. This prevents other workers from thinking it's stuck. If a worker crashes mid-execution, the claim expires after a configurable idle time (default: 90 seconds) and the run is handed to a healthy worker. The workflow then re-executes from its last checkpoint.

When execution completes or fails, the worker reports the terminal state to the server.

Scaling

Workers scale naturally. You can add capacity in several ways:

Run multiple instances of the same worker to share load. Each gets a portion of the work automatically:

const worker1 = worker({ workflows: [orderWorkflowV1] });
const worker2 = worker({ workflows: [orderWorkflowV1] });

const handle1 = worker1.spawn(aikiClient);
const handle2 = worker2.spawn(aikiClient);

Specialize workers by registering different workflows on different workers. Each worker only handles the workflows it knows about.

Shard by region or tenant using shards. A worker with shards: ["us-east"] only processes workflow runs routed to that shard.

Graceful Shutdown

Always handle shutdown signals to let active workflows complete:

process.on("SIGTERM", async () => {
  await handle.stop();
  process.exit(0);
});

The stop() method on the handle signals the worker to stop accepting new work, waits for active executions to finish (up to gracefulShutdownTimeoutMs), then returns. Any workflows that don't complete in time keep their state in the database; once their claims go stale, other workers pick them up.

Configuration Reference

Worker configuration is split between params (identity) and options (tuning).

Params are passed directly to worker():

ParamDescription
workflowsWorkflow versions this worker executes
subscriberOptional subscriber factory for work discovery (default: claims from the server over HTTP). Use redisSubscriber() from @aikirun/redis for lower-latency delivery

Options are passed via options param or with() builder:

OptionDefaultDescription
maxConcurrentWorkflowRuns1Max parallel executions
gracefulShutdownTimeoutMs5,000Shutdown wait time (ms)
workflowRun.heartbeatIntervalMs30,000Heartbeat frequency (ms)
shardsShards to process

Pluggable Subscribers

By default, workers claim work from the server over HTTP, which requires no setup beyond the Aiki server connection. For sub-second work discovery, install @aikirun/redis:

npm install @aikirun/redis
import { redisSubscriber } from "@aikirun/redis";

const aikiWorker = worker({
  workflows: [orderWorkflowV1],
  subscriber: redisSubscriber({ host: "localhost", port: 6379 }),
});

You can also implement your own subscriber by providing a function that matches the CreateSubscriber type from @aikirun/types/infra/queue. See Subscribers for how the implementations work and what custom subscribers must provide.

Next Steps

  • Client — Connect to Aiki server
  • Workflows — Define workflow logic
  • Tasks — Create reusable task units

On this page