📄️ Signals
Signals allow you to trigger events in a workflow from outside the workflow. This can be useful for reacting to external events, enabling human-in-the-loop interventions, or for signaling the completion of an external task.
📄️ Queries
Queries allow you to retrieve information about the current state of a workflow without affecting its execution. This is useful for monitoring and debugging purposes.
📄️ Timers
The framework provides the ability to suspend the execution of a workflow and resume at a later time. These are durable timers, meaning they survive restarts and failures while remaining consistent with workflow replay semantics. This can be useful for implementing delays, retry logic, or timeouts.
📄️ Signal + Timer
Workflow\V2 supports both await($condition, timeout $key) for timeout-backed condition waits and await('signal-name', timeout: $seconds) for timeout-backed named signal waits.
📄️ Side Effects
A side effect is a closure containing non-deterministic code. The closure is only executed once and the result is saved. It will not execute again if the workflow is retried. Instead, it will return the saved result. This makes the workflow deterministic because replaying the workflow will always return the same stored value rather than re-running the non-deterministic code.
📄️ Heartbeats
Heartbeats let a long-running activity report that its current attempt is still alive.
📄️ Child Workflows
The current Workflow\V2 slice supports durable child workflows through straight-line child() calls and through all([...]) fan-in barriers that can be child-only, mixed with activities, or nested inside larger all([...]) groups. Together, these give a parent workflow a durable way to schedule one or more sub-workflows and wait for their outcomes without keeping the parent process alive.
📄️ Concurrency
In Workflow\V2, named workflows use straight-line helpers inside an ordinary handle() method: activity(), await(), timer(), sideEffect(), getVersion(), and the other single-step helpers suspend directly under the hood instead of forcing yield into every workflow body. Use await('signal-name') for one named signal value. Named v2 workflows are straight-line only, so do not yield from the workflow body.
📄️ Sagas
Sagas are an established design pattern for managing complex, long-running operations:
📄️ Events
Lifecycle events are dispatched at key stages of workflow and activity execution to notify your application of progress, completion, or failures. These are standard Laravel events — register listeners in your EventServiceProvider or with Event::listen().
📄️ Webhooks
The framework provides webhooks that allow external systems to start workflows and send signals dynamically. This feature enables seamless integration with external services, APIs, and automation tools.
📄️ Continue As New
The Continue As New pattern allows a running workflow to restart itself with new arguments.
📄️ Versioning
Since workflows can run for long periods, sometimes months or even years, it's common to need to make changes to a workflow definition while executions are still in progress. Without versioning, modifying workflow code that affects the execution path would cause non-determinism errors during replay.
📄️ Cancel and Terminate
Cancel and terminate are first-class durable commands that close a running workflow. Both are recorded in command history, appear in typed history events, and surface in Waterline.
📄️ Search Attributes
Search attributes are typed, indexed key-value pairs that a workflow can upsert at any point during execution. Unlike visibility labels (which are set once at start time), search attributes can be updated as the workflow progresses, making them ideal for tracking workflow status, customer identifiers, or any operator-visible metadata that changes over the lifetime of a run.
📄️ Memo
Memos are non-indexed key-value metadata that a workflow can read and update at any point during execution. Unlike search attributes (which are indexed and filterable), memos are designed for richer, structured metadata that appears in detail views and history exports but is excluded from fleet-wide filtering and sorting by contract.
📄️ Timeouts
Workflow-level timeouts let you bound how long a workflow is allowed to run. There are two timeout scopes:
📄️ Schedules
Schedules let you start workflow runs on a recurring basis using cron expressions. Each schedule is a named, durable entity that the engine evaluates on every tick to determine whether a new run should be triggered.