Register your interest: Tag @Cody, get an agent
BlogEngineering

Long-running workflows explained: it is all about the waiting

A process measured in days is mostly a process that is waiting. The kinds of wait, what each needs, and why a workflow that stops is harder to notice than one that fails.

Osman RamadanOsman Ramadan11 min read

Summarize with AI

Long-running workflows explained: it is all about the waiting
On this page

A long-running workflow is a process that takes days or weeks rather than seconds. Onboarding, contract approval, a refund that depends on a return arriving, a trial that ends in thirty days.

The steps in these processes are usually quick. What makes them long is waiting — for a person, for a date, for an external system, for a customer who may never respond. Designing one well is almost entirely about designing the waits, and the failure that matters is not a step erroring but a process stopping quietly with nobody noticing.

What we'll cover

The four kinds of wait

Naming them separately is useful, because each needs different handling.

A person must do something — approve, review, supply information. Unbounded, and the most common reason processes stall.

A date or duration. The trial ends, the notice period expires, the review is due. Predictable and the easiest to handle.

An external system must report something — a payment clears, a delivery is made, a document is signed. Bounded in principle and frequently not in practice.

An event that may never occur. The customer responds, the return arrives, the counterparty countersigns. This is the category that needs an explicit answer for the case where it does not.

Most real processes contain several, and the ones that go wrong usually have one wait nobody thought about as a wait at all.

Waiting for a person

Give them everything needed to decide. An approval request requiring somebody to open three systems is an approval that gets deferred.

Ask in the place they already are, rather than somewhere they must remember to check.

Set a timeout on every human step. Always. A process waiting on a person with no timeout will wait indefinitely, and nothing will tell anybody.

Escalate by age. A nudge to the person, then their manager, then a named fallback — rather than a single reminder that is also ignored.

Have an answer for absence. Holidays, departures, and role changes all happen during a process that takes three weeks, and a request addressed to somebody who has left waits forever.

Record who decided and when, since this is usually the reason the process is being tracked in the first place.

Waiting for a date

The easy case, with two things that catch people out.

Timezones. "Thirty days" and "the thirtieth of next month at nine" behave differently across regions and across daylight saving transitions.

The date can change. A contract end date gets amended while the process is waiting for it, and a process holding a copy of the old date will act on the wrong day.

Re-read the date rather than caching it, or handle the amendment as an event that adjusts the wait.

Consider working days, since "five days to respond" usually means working days to a person and calendar days to a naive implementation.

Fire slightly early where it matters. A notice that must be given before a date should allow for the recipient not reading it the same hour.

Waiting for an external system

Prefer a callback to polling where the system offers one, since polling for days is wasteful and polling intervals add latency to the whole process.

Assume the callback may not arrive. Registrations get removed, endpoints have outages, and third parties have incidents — so a callback wait needs a polling fallback or a timeout.

Set a bound. "Until the payment clears" needs a maximum, after which somebody is told, because payments occasionally do not clear and nothing announces that.

Handle the response arriving twice, which is normal.

Handle the response arriving before you are ready — a fast external system can respond before your process has recorded that it is waiting, which produces a mysterious lost callback.

Record what you are waiting for, in a form a person can query, because "which processes are waiting on that system" is the question during their outage.

Waiting for something that may never come

The category that needs a deliberate decision rather than a mechanism.

Decide what happens if it never arrives, at design time, for every wait of this kind. Not "it stays open" — an actual outcome.

Cancel, escalate, or proceed with a default are the three real options, and which is right depends on the process.

Set the limit by what the business needs, not by what is technically convenient. If a quote is valid for fourteen days, the wait should end there.

Tell the other party before it ends. A reminder before cancellation converts a proportion of non-responses into responses, which is the cheapest improvement available.

Record the outcome as a result, not as a failure. A process that ended because the customer did not respond completed correctly, and reporting it as an error obscures the ones that did fail.

Report the rate. How many processes end this way is a product signal — a high rate usually means the request was unclear or went to the wrong person.

Detecting the stopped process

The operational problem, and the one that distinguishes a workflow that works from one that appears to.

Stopped is not failed. A failed step errors somewhere; a stopped process produces nothing, and nothing generates no alert.

Report the longest-running instances, weekly. A short list, always interesting, and the only thing that reliably surfaces this.

Report by step. Knowing that eleven processes are waiting at the same approval is a different fact from eleven processes being old, and it points at the cause.

Compare against expected duration. A process taking four times its normal duration is worth a look even if no individual wait has timed out.

Give somebody the list. An operational view nobody opens is the same as no view, which is why this belongs in a weekly report rather than a dashboard.

Make cancellation possible. Some stuck processes should simply be ended, and without a supported way to do that people resort to editing data directly.

The world changes while you wait

The property unique to long processes, and the source of the strangest bugs.

People leave. The approver, the owner, the requester — all can be gone before the process completes.

Records change. The customer's plan, the order's contents, the contract's terms may all be amended mid-process.

Prices and rules change. A process started under one policy completing under another is a question somebody will eventually ask about.

Decide whether to re-read or to snapshot, per field, explicitly. A process that snapshotted an address will deliver to the wrong one; a process that re-reads a price may charge something the customer never agreed to.

The code changes too, which means a process started weeks ago is completing under logic that has since been deployed several times.

Record what the process saw, at the points where it mattered, so the question "why did it do that" is answerable afterwards.

Letting people see where something is

The request that arrives once a long process is in production, usually from support.

Somebody will ask where a specific case is. A customer chasing a refund, a salesperson chasing an approval, an agent chasing an onboarding.

Answering from logs does not scale. If the answer requires an engineer, it will be asked of an engineer repeatedly.

Expose a status per instance in terms the asker understands — "waiting for the signed contract", not "step 4 of 9".

Say what happens next and roughly when, since that is the actual question behind "where is it".

Show who it is waiting on, where that is a person, because the answer is frequently that somebody needs a nudge.

Let support see it without engineering, which removes a recurring interruption and, more importantly, means customers get answered the same day.

This is usually a small piece of work and it is the one that makes the difference between a workflow that is operationally healthy and one that generates a steady trickle of questions nobody has time for.

Building one with CodeWords

CodeWords connects to more than 3,000 integrations, and the waiting, the timeouts, and the resumption are part of describing the process rather than infrastructure to operate.

  1. Open CodeWords and start a new automation.
  2. Describe the process in plain language to Cody, the automation builder: the steps, what each waits for, and where a person decides.
  3. Describe the exceptions: an approval that never comes, an external system that does not respond, a record changed mid-process.
  4. Connect the systems involved once and reuse the connections.

You describe the outcome; Cody builds it, connects it, and deploys it. The free plan covers light use, with Pro at $39 per month and Business at $100 per month as usage grows; details are on the pricing page.

What to get right first

A timeout on every wait, with a defined outcome — not a longer wait, an actual decision about what happens. A process with an unbounded wait does not fail; it stops, and a stopped process is invisible to every form of monitoring that looks for errors.

Two habits make the difference. Decide per wait whether the answer on timeout is cancel, escalate, or proceed with a default, since "it stays open" is how a process ends up three months old with nobody responsible. And report the longest-running instances weekly, because that short list is the only thing that reliably surfaces processes which stopped without erroring.

Frequently asked questions

Why do long-running processes get stuck?

Because a wait had no timeout. A person left, an external callback never arrived, or a customer did not respond — and with no bound, the process simply waits, producing no error and no signal anywhere.

What should happen when an approval never comes?

Whatever you decided at design time: escalate, cancel, or proceed with a default. "It stays open" is not a decision, and it is how processes end up months old with nobody responsible for them.

How do I find stopped processes?

Report the longest-running instances weekly, grouped by which step they are waiting at. Monitoring that looks for errors will never find them, because stopping produces no error.

Should a process re-read data or use what it saw at the start?

Per field, deliberately. Snapshotting an address means delivering to the old one; re-reading a price means charging something the customer never agreed to. Both are wrong in different situations, so the decision has to be explicit.

What about the person who approved leaving mid-process?

Plan for it. A three-week process will outlive somebody's role change or departure, so every human step needs a fallback and an escalation that does not depend on one individual still being there.

Is a customer not responding a failure?

No, it is an outcome. Record it as such rather than as an error, or the genuine failures are buried among them — and report the rate, since a high one usually means the request was unclear rather than that customers are unresponsive.

Why did a callback go missing?

Either the registration was removed, or it arrived before your process had recorded that it was waiting. The second is easy to miss and produces a process that waits forever for something that already happened.

How do people find out where a specific case is?

Expose a per-instance status in terms the asker understands — "waiting for the signed contract" rather than "step 4 of 9" — with what happens next and who it is waiting on. If answering requires an engineer, it will be asked of one repeatedly.

What is the most common operational request?

Support asking where a customer's case has got to. It is a small piece of work to expose and it removes a steady trickle of interruptions while letting customers be answered the same day.

Get started today

Your first workflow is free to build.

Describe what you need. Cody handles the build, the connections, and the deployment.