
Durable execution vs queues: what an AI workflow actually needs
Compare durable execution and queues for AI workflows, then choose the right architecture for retries, state, approvals and safe recovery.
Durable execution vs queues is not a contest between a modern tool and an obsolete one. A queue reliably delivers units of work. Durable execution preserves the progress and control flow of a whole process across failures, delays and restarts. An AI workflow often needs both capabilities, but it does not always need a dedicated workflow engine.
The distinction becomes important when an agent stops being one background task. It calls a model, searches for evidence, invokes tools, waits for approval, retries a provider and resumes after a deployment. A queue can run every individual step. It does not, by itself, remember why those steps exist, which decisions were accepted or what should happen after a three-day pause.
I use a simple rule in architecture reviews: choose the smallest mechanism that makes the business process recoverable. Sometimes that is a Laravel queue plus explicit database state. Sometimes the application has quietly grown into a workflow engine, and adopting durable execution removes more code than it adds.
A queue delivers work; durable execution preserves a process
A message queue answers an operational question: which worker should receive this job, and what should happen if that worker does not acknowledge it? It gives applications asynchronous delivery, buffering, concurrency control and retry mechanisms. Those are foundational capabilities. Laravel queues make them accessible through a consistent API across backends such as Redis, Amazon SQS and relational databases.
A durable workflow answers a larger question: how can this multi-step process continue from its last accepted point after the code stops running? Its unit of identity is the workflow instance, not a single message. It records enough history or state to reconstruct where the process is, which timers are pending and which external results have already been accepted.
| Concern | Queue | Durable execution |
|---|---|---|
| Primary abstraction | Message or job | Workflow instance |
| Progress | Application stores it | Runtime records it |
| Retry scope | Usually one job | One activity or workflow policy |
| Waiting | Delayed message or scheduler | Durable timer or suspended workflow |
| Human input | Custom state and dispatch logic | Signal or event resumes the run |
| Code changes | Version payloads and handlers | Version workflow logic and replay |
| Observability | Jobs, logs and custom timeline | Workflow history and activity status |
Neither column guarantees that an external API performs an action exactly once. A payment, email or publication can succeed remotely while its response is lost. Both designs still need stable operation identifiers, provider idempotency where available and reconciliation for ambiguous outcomes. Durable execution reduces orchestration work; it does not repeal distributed systems.
A queue is enough more often than workflow vendors suggest
A plain queue remains a good choice when a job is short, independent and safe to repeat. Generating a thumbnail, indexing a document, sending a notification from an outbox record or recalculating one projection does not automatically justify a new platform. The application can dispatch work, acknowledge success and move failures to a visible failed-jobs path.
Queues also work well for multi-step flows when the number of steps is small and the domain already has explicit state. A Laravel application can model uploaded -> extracted -> reviewed -> published in SQL, dispatch one bounded job per transition and use a transactional outbox to avoid losing the next command between a database commit and queue publication.
I would stay with queues when most of these statements are true:
- the process finishes in minutes rather than days;
- there are few branches, timers and compensation paths;
- jobs can load all required context from durable storage;
- each job has an obvious idempotency boundary;
- operators can understand the run from existing domain records;
- the team is comfortable owning transition and recovery code;
- a failed deployment does not require reconstructing an in-memory call stack.
The important phrase is explicit state. Chaining six queue jobs is not the same as defining a six-state workflow. A chain expresses dispatch order. The domain model must still decide whether a stale job may run, whether approval applies to the current artifact and what “resume” means after two steps have completed.
The signals that a queue is becoming a home-made workflow engine
The first warning is not job count. It is coordination code. If every feature adds another status column, delayed message, retry counter, watchdog command and administrative repair script, the application is paying the workflow-engine cost without receiving a coherent execution model.
Look for these signals together:
- Long waits: workflows pause for human approval, rate-limit reset, a vendor webhook or a scheduled business date.
- Branching and fan-out: one decision starts several tasks whose results must be collected before the next step.
- Frequent partial failure: retrying the whole process is wasteful or unsafe, while identifying the correct resume point is difficult.
- Compensation: completed actions cannot be rolled back transactionally and need business-specific counter-actions.
- Operator intervention: support staff need to inspect, pause, retry, cancel or repair one process instance.
- Cross-service ownership: no single application's state machine describes the end-to-end process.
- Recovery code dominates business code: the happy path is readable, but dozens of handlers recreate timers, history and resume logic.
One or two signals do not force a migration. A two-step approval flow can remain perfectly maintainable in Laravel. The case for durable execution strengthens when the signals compound and every new branch multiplies the recovery combinations the team must implement and test.
How durable execution survives a stopped process
Durable execution platforms use different terminology, but the core idea is stable: workflow progress is persisted outside the worker process. Temporal, for example, describes a workflow execution as durable, reliable and scalable, with commands and events recorded in an event history. AWS Step Functions persists state between steps and offers workflow types with different duration and execution semantics.
Workflow code usually separates deterministic orchestration from non-deterministic activities. The orchestrator decides which step should run next. Activities perform network calls, database writes or other work that can fail. If a worker disappears, another worker can reconstruct the orchestrator's decisions from recorded history and schedule only the missing activity.
That replay model creates rules that ordinary queue handlers do not have. Workflow code cannot casually read the current clock, generate a random value or call an API inside replayed logic unless the platform provides a deterministic abstraction. Code changes must remain compatible with histories that were produced by older versions. This is real engineering work, not magic hidden behind a workflow() function.
Durable timers are another major difference. The workflow can logically sleep for a week without occupying a PHP process or worker thread. An approval event can resume the same workflow identity with its prior decisions intact. With queues, the application builds the equivalent from persisted state, delayed jobs, event handlers and guards against duplicate or stale delivery.
AI workflows make orchestration failures more expensive
AI workloads expose the difference because their steps are slow, probabilistic and expensive. Repeating a deterministic database read may be harmless. Repeating a model call can produce a different answer and consume more money. Repeating a tool call can publish twice. Losing the evidence behind an approved answer can make the audit trail meaningless.
A production agent may need to preserve:
- the prompt, model and schema version used for a decision;
- the source IDs and artifact hashes accepted at each checkpoint;
- tool operation IDs and ambiguous outcomes awaiting reconciliation;
- attempt, token, cost and elapsed-time budgets;
- the exact artifact a human reviewed and approved;
- policy decisions that constrain which action may happen next.
This is why long-running AI workflows should be durable data, not one immortal worker. It is also why I test state transitions separately from model outputs. Whether the orchestration lives in application tables or a workflow platform, deterministic control must surround the probabilistic model.
Durable execution does not mean storing an unlimited chat transcript in workflow history. Large prompts, documents and model responses usually belong in object storage or another artifact store. The workflow history should keep stable references, hashes and the decisions required to resume. Otherwise history becomes expensive, sensitive and difficult to evolve.
What both architectures still need
Platform comparisons often exaggerate the guarantees on both sides. A queue is not unreliable merely because the application owns state. A workflow engine is not exactly-once reality merely because it can replay orchestration. The external world stays outside the local transaction.
Whichever architecture you choose, define these contracts:
- Idempotency: the same logical operation uses the same key across retries.
- Timeout classification: distinguish known rejection, known success and unknown outcome.
- Retry budget: bound attempts, elapsed time and cost rather than retrying forever.
- Reconciliation: ask the provider what happened before repeating an ambiguous write.
- Compensation: define what can mitigate an irreversible action when later steps fail.
- Versioning: keep old payloads, states and running workflows compatible with new code.
- Audit evidence: record who or what made a decision and which artifact it concerned.
A useful architecture review therefore starts with failure semantics, not product logos. Ask what happens if the worker stops immediately before and after every external call. Ask how a deployment affects work that started yesterday. Ask whether a duplicate approval, webhook or queue delivery changes the outcome. The missing answers reveal the real infrastructure requirement.
The PHP and Laravel decision
PHP is not a reason to avoid durable workflows, and it is not a reason to adopt them. Laravel queues, scheduled commands, events, database transactions and an outbox can support substantial orchestration. PHP workers remain disposable while SQL holds accepted business state. This architecture is direct, debuggable and familiar to many teams.
I would begin with a queue-first design for a Laravel product when the workflow belongs to one bounded context. Use a workflow table with a version column, append-only transition records, immutable artifact references and outbox commands. Make each job attempt one transition. Reject stale versions and treat duplicate delivery as expected.
I would evaluate a dedicated durable execution platform when the process crosses services, waits for days, has many parallel branches or requires extensive operational controls. The calculation should include the custom machinery it replaces: polling, timers, repair commands, transition history, retry coordination, workflow search and operator tooling.
Do not compare the platform's subscription or operational cost with the queue broker alone. Compare it with the queue broker plus the state tables, schedulers, dashboards, on-call procedures and engineering time needed to produce equivalent behaviour. Also count the new platform's cost: another runtime, deployment model, programming constraints and skills the team must own.
A migration path that does not begin with a rewrite
If the current queue architecture hurts, make its implicit contracts visible before moving them. A workflow engine cannot clarify a process the team has not defined. I use this sequence:
- Name the workflow identity. Give every run a stable ID that appears in jobs, artifacts, logs and external operation references.
- Draw the state graph. Include waits, cancellation, timeout, exhausted retry and manual-intervention paths, not only success.
- Separate orchestration from effects. Move provider calls behind activity-like services with explicit input, output and idempotency contracts.
- Persist checkpoints. Record accepted artifacts and decisions so queue jobs can already resume safely.
- Measure coordination code. Identify which timers, pollers, retry handlers and repair tools a platform would replace.
- Migrate one painful workflow. Choose a process with real waits or partial failures, then compare operability and development cost.
This preparation is useful even if the team stays with queues. It turns accidental chains into an explicit application workflow. If the team migrates, activity boundaries and idempotency keys already exist, reducing the risk of moving a fragile design into a more sophisticated runtime.
Durable execution vs queues: the decision checklist
| Question | Queue-first answer | Durable execution answer |
|---|---|---|
| How long can one run live? | Seconds or minutes | Hours, days or months |
| How complex is control flow? | Few linear transitions | Branches, joins, timers and signals |
| Where does progress live? | Clear domain records already exist | Custom coordination state keeps growing |
| How is recovery handled? | Retry one bounded, idempotent job | Resume from recorded workflow history |
| Who operates failures? | Developers inspect jobs and records | Operators need workflow-level controls |
| How many services participate? | One bounded context | Several independently deployed services |
| What is the team ready to own? | State and orchestration code | A workflow platform and replay constraints |
The practical answer is often layered. A durable workflow engine may coordinate the business process while queues or task workers execute activities. A Laravel application may keep its domain state and expose commands to the orchestrator. Choosing durable execution does not eliminate queues; it changes which component owns progress and recovery.
Start with the failure you need to survive. If delivering one independent task again solves it, use a queue. If the system must remember a sequence of accepted decisions across workers, deployments and long waits, model a durable workflow. Build that model explicitly in your application while it remains small, and consider a dedicated engine when coordination becomes a product of its own.
Sources checked on October 16, 2026: the official Temporal documentation on workflow executions and event history, the AWS documentation on Step Functions workflows, and the Laravel 13.x documentation on queues, retries, timeouts and workers. Product capabilities and limits change, so verify them before an architecture decision. This article reflects practical experience with PHP backends, queues, automation and AI agents. It was prepared with AI assistance and editorial review. Cover source: web network photograph on Pixabay.
If your AI workflow is accumulating retry handlers, repair scripts and unclear resume paths, I can help review its boundaries and recovery model. See my AI engineering consulting work or contact me.
