If you are building workflows that run for hours, days, or weeks, "it works most of the time" is a liability, not a feature. A recent deep dive from Escepine argues that deterministic execution is the only way to ensure reliability in long-running, mission-critical systems. The core premise is simple but often ignored: without a predictable way to reconstruct state from history, recovering from a crash is just a guessing game.
The Failure of Naive Retries
The article dismantles the common developer habit of treating retries as a silver bullet for distributed system failures. It points out that a timeout does not mean an operation failed; the server might have processed the request successfully while the response was lost in transit. If your workflow blindly retries a side-effecting operationβlike charging a credit card or provisioning infrastructureβyou risk duplicating actions. Deterministic execution solves this by ensuring that if a workflow resumes, it replays its history to determine what already happened, rather than re-executing logic that may now yield different results due to changed external state.
Why In-Memory State Doesn't Cut It
For short-lived tasks, keeping state in variables is fine. For workflows that wait for human approvals or external events, in-memory state is fragile. The piece highlights that variables like currentStep or paymentCompleted vanish when the process dies. Without durable execution history, a worker restart leaves the system blind. Escepine advocates for an architecture where progress is recorded externally, allowing any worker to pick up the slack and reconstruct the workflow's logical path exactly as it was before the interruption.
Handling Nondeterminism in Code
A major technical hurdle in deterministic execution is handling operations that naturally change over time, such as Date.now() or Math.random(). The article explains that if these values are read during replay, they might differ from the original execution, causing the workflow to take a different branch. The solution is to isolate these nondeterministic calls. By capturing the result of these operations during the first run and storing them in the history, the workflow can reuse those recorded values during replay, ensuring logical consistency even when the outside world has moved on.
Key Takeaways
- Determinism does not mean the external world is predictable; it means your workflow's logic remains consistent when replayed against recorded history.
- Retries are dangerous for side-effecting operations unless combined with idempotency and durable state tracking.
- Nondeterministic operations (time, random) must be wrapped and recorded to prevent branching logic from diverging during recovery.
- The goal is not to prevent failures, but to make recovery a standard, predictable part of the execution model.
The Bottom Line
Deterministic execution is not a silver bullet that eliminates the need for idempotency or careful side-effect handling, but it is the foundational requirement for trust in long-running systems. Without it, you are not building reliable workflows; you are just delaying the inevitable debugging nightmare.