Workflow states and job history
A durable state model for GTM work that separates waiting, running, completed, suppressed, retried, and failed items from the business outcome.
On this page
status = complete is not a job history. It cannot tell you whether the item was completed, suppressed, or accidentally skipped.
State model
waiting → running → completed
↘ deferred ↗
↘ suppressed
↘ failed → retrying → runningUse one current state for routing and an append-only event history for diagnosis.
| State | Meaning | Owner |
|---|---|---|
| Waiting | Eligible work has not started | Workflow owner |
| Running | A job has claimed the item | Job runner |
| Deferred | Safe to revisit later | Named queue owner |
| Completed | Business completion evidence exists | Receiving owner |
| Suppressed | Control intentionally stopped it | Control owner |
| Failed | The system could not finish | Operations |
Event record
{
"run_id": "run_0042",
"state": "failed",
"at": "2026-08-23T16:02:10Z",
"attempt": 2,
"step": "create-task",
"reason_code": "provider-timeout",
"next_owner": "revops"
}Record the step, attempt, reason, and next owner. Logs that cannot be joined to the CRM subject are hard to operate.
Notifications close the loop
Notify on state changes that need a person: overdue, failed after retry, suppressed by a policy, or completed with an unexpected outcome. Do not notify on every successful low-risk step. A notification should include the record, state, reason, deadline, and permitted next action.
Storage choices
Use native CRM fields when the state is needed for routing and reporting. Use a related job or event object when one subject can have many runs. Use an external queue when throughput or retry behavior exceeds the CRM's role. Keep the same state names and IDs across the boundary.
Separate current state from history
Keep one current-state view for routing, but append an immutable event for every transition. The event should include run ID, subject ID, previous and next state, reason, actor, timestamp, workflow version, and correlation ID. Corrections create new events; they do not rewrite old ones.
Define permitted transitions. For example, waiting may move to running, suppressed, or expired, but not directly to completed without a completion event. Rejecting impossible transitions catches duplicate callbacks and out-of-order updates before they corrupt reporting.
Make history operational
Build views for open work by age and owner, failed work by reason, retries near their limit, and runs with no event inside the expected window. Retain enough history to investigate business disputes and compare versions. Test that every terminal state has a reason and that every external action can be traced back to one run and one policy version.
Related: Retry, defer, and escalation, Exit and completion rules, and Handoff contracts.
Related guides
FAQ
- Which states should a GTM workflow record?
- At minimum record waiting, running, completed, suppressed, deferred, and failed. Add retrying or needs-review when those states change who owns the next action. Keep the business outcome separate from the job state.
Get the next guide
New guides and the occasional note on GTM tooling. Don't worry, I won't drop you into a three-month nurture.