Salman Parvez
Self-taught full-stack engineer. Founder of ML Systems, a Rhode Island construction tech company. Shipped a React Native app to both stores
The argument gets stronger if you add why the request-response version fails badly rather than gracefully. A long AI call inside an HTTP request does not just make the user wait - it holds memory for the whole duration, so under load you do not get a slow service, you get an OOM kill. Every in-flight request is sitting on a context, and the failure arrives all at once. Two things worth pairing with the workflow queue. Idempotency keys, because retries are the entire point of a durable workflow and an agent step that charges something or sends an email twice is worse than one that failed. And a bound on queue depth with early rejection, since accepting work you cannot finish turns a capacity problem into an outage - a fast 503 is friendlier than a job that sits for twenty minutes and times out. Separating queue wait from execution time in your metrics is the other habit that pays off: they demand opposite fixes, and a single p95 blends them into something you cannot act on.
Per-step retries are the right unit, and they pull a second requirement in behind them: each step has to leave a record of what it produced and from which input, or a retry can silently redo work against a newer version of the document than the step before it saw. We run intake this way for a house — assessor harvest, facade vision, sketch reconciliation, compression — and the thing that made retries safe wasn't the queue, it was giving every step's output a source and a version, so a re-run that disagrees with the earlier run shows up as a conflict instead of overwriting it.