Skip to content

External Workers

Any step handler not registered as a built-in is automatically dispatched to the external worker queue. Workers poll for tasks via REST, execute them in any language, and report results back.

Flow

  • 1.Engine encounters unknown handler name → creates worker task
  • 2.Worker polls: POST /workers/tasks/poll { handler_name: "process_image" }
  • 3.Worker executes, sends heartbeats every 15–30s for long-running tasks
  • 4.Worker reports: POST /workers/tasks/{id}/complete { output: {...} }
  • 5.Engine resumes workflow from where it left off

Properties

  • Pull-basedNo message broker needed. Workers poll at their own pace.
  • At-least-onceHeartbeat timeout (60s) + reaper (30s interval) ensures no stuck tasks.
  • Error classificationWorkers declare retryable vs permanent failures. Retryable deletes the task for re-dispatch; permanent marks the instance failed.
  • Concurrent workersSKIP LOCKED prevents double-claiming. Scale horizontally by running more workers.

Heartbeat

Send POST /workers/tasks/{id}/heartbeat every 15–30 seconds for tasks that run longer than 60 seconds. Tasks without a recent heartbeat are reclaimed by the reaper and returned to the queue for re-dispatch.

Task queue routing

Assign steps to named queues. Dedicated worker pools poll their specific queue — useful for isolating high-priority, GPU-intensive, or region-specific workloads from general-purpose workers.

// Step with queue assignment
{
  "type": "step",
  "id": "render_video",
  "handler": "video_renderer",
  "queue_name": "gpu-workers"
}
POST /workers/tasks/poll/queue
{
  "queue_name": "gpu-workers",
  "handler_names": ["video_renderer", "image_upscaler"]
}

Workers that poll without a queue name claim from the default queue. Tasks claimed on the wrong queue are never released to other queues — they wait until the correct worker type polls.