Signals
Release a worker slot until another process delivers a named JSON payload.
HandlerContext.waitForSignal records a durable boundary and releases the lease. When another
process delivers the named signal, Workhorse makes the same logical attempt ready and restarts the
handler from its entry point.
const approval = await context.waitForSignal<{ approved: boolean }>("approval");
if (approval.approved) await publishOrder();Checkpoint earlier effects because replay starts from the top. When replay reaches the same name,
waitForSignal returns the retained payload.
Go handlers can pass ExternalWaitOptions when the boundary needs a shorter lifetime. Python
handlers pass timeout_ms for the same boundary.
Deliver once, retry safely
Applications call Queue.sendSignal(jobId, name, payload, request) with an idempotency key and a
trusted actor. An equivalent network retry returns the retained delivery. Reusing a key with
changed payload or attribution conflicts, and a competing late delivery returns the accepted
winner without resuming the handler again.
If another transition has already closed the boundary, the delivery returns stale and leaves the
retained outcome unchanged.
A delivery before the wait exists is rejected rather than buffered. A timeout, job deadline, or cancellation closes the boundary, so replay cannot continue with an invented payload.
Admin.listSignalWaits() provides the actionable operator projection. The dashboard uses the same
public method, but its server replaces browser-supplied attribution with the authenticated actor.
Go applications deliver through Queue.SendSignal with ExternalWaitDelivery. The returned
SignalDeliveryResult contains the database status and retained payload.
TypeScript handlers call ctx.waitForSignal and pass timeoutMs when the wait needs a deadline. Go
uses HandlerContext.WaitForSignal; both return a nextCursor that prevents an earlier signal from
being consumed again.
Next
- Human waits — collect an operator decision with stored context
- Durable execution — understand handler replay
- Agentic flow — wait for approval inside a durable loop
Exact signal statuses, bounds, and transitions: architecture reference.