Skip to content
Technical preview. This site is published for review. Everything on it, including the API, tokens and module protocol, is subject to change.
Guarantees

What AutoFlow guarantees, and what it does not

Every line below is traceable to the engine’s documentation or code. Where another page seems to promise more, this one is right.

Guaranteed

  • A workflow survives crashes. It survives a restart, a failure of the instance running it and a network outage, and may run for weeks; work a dead instance left in flight is queued again by the next instance that claims its shards.
  • A round is all or nothing. Everything a round of the script produces commits in one transaction at the moment the script waits, or not at all; nothing is ever half-applied.
  • History is append-only. Events are never rewritten and their sequence ids are gapless, so what happened is what history says happened.
  • One workflow per idempotency key. Within a namespace, a key maps to at most one workflow for as long as that workflow’s data exists; resubmitting it returns the existing workflow instead of starting a second.
  • At most one active run per workflow. Only one round of a given workflow executes at a time, on one instance, so rounds never race each other.
  • It scales across nodes. The keyspace is split into shards, each owned by at most one AutoFlow instance at a time; capacity grows by attaching another workflow database, which running instances pick up without a restart.
  • Waiting is free. A workflow that sleeps or waits on a channel holds no resources; its state is already durable, so suspending it costs nothing.
  • Action calls ride out outages. When the call into a module fails at the infrastructure level, autocore retries it, by default 20 attempts over about an hour and three quarters, before the workflow sees an error; an error the module returns as its answer is final.
  • Every attempt carries the same idempotency key. Each action invocation carries a key derived from the workflow and the call site, presented unchanged on every retry, so the destination can collapse repeats.
  • The script is sandboxed. A workflow has no filesystem, no network, no environment, no randomness and no wall clock; its only ways out are actions, print(), and a time.now() derived from history.
  • Secrets are opaque. A sensitive_string or sensitive_bytes value can be handed to an action but never read, printed, hashed or probed with in by the script.
  • Tokens gate access. Reading, canceling or sending to a workflow requires that workflow’s token, so holding a workflow key or an idempotency key is not holding the workflow.

Not guaranteed

  • Exactly-once side effects. An action can run more than once if a crash lands between its work and the recording of its result; the guarantee is at-least-once execution with a stable idempotency key, which the module or the system behind it has to honor.
  • Unbounded lifetime. A workflow has a schedule-to-complete timeout of 30 days by default and 60 days at most; when it elapses, the workflow ends as timed out.
  • Retention beyond 90 days. Workflow data is retired after the retention window, 90 days by default; a workflow idle for longer than that, sleeping or waiting, is retired with it and silently gone, so 90 days is the longest supported wait.
  • Delivery of every channel value. A workflow receives at most 10,000 channel values; sends beyond that are refused, a value accepted just under the cap can still be dropped, and a value with a forged channel token is accepted and dropped without the sender noticing.
  • Immediate cancellation. Cancellation is an asynchronous, best-effort signal: it takes effect at the workflow’s next wait, and a workflow that never waits again never observes it.
  • Recovery from every crash, forever. Re-queueing a task after an infrastructure abort has a finite budget, five attempts by default; once spent, the workflow ends as system-failed.
  • Upgrading a running workflow. A workflow runs the exact script bytes it was started with, stored in its history; changing the script in your repository does not change a running workflow, and there is no versioning API to migrate one.

Sources: doc/autocore.md in the Relay repository and the AutoFlow user manual.

Last updated on