Skip to content

Best Practices

Authoring

  • Give every durable await a stable id.
  • Change behavior with a new workflow version and fingerprint.
  • Keep I/O in activities. Keep decisions in the workflow function.
  • Use parallel / race / quorum, not Future.wait.
  • Attach a WorkflowDocument when the inspector needs a pre-run map.

Activities

  • Always persist and send idempotencyKey.
  • Heartbeat work that can outlive a lease.
  • Prefer start-external-job + signal over a multi-day in-process activity.
  • Keep old activity versions deployed while referenced runs exist.

Products

  • Talk to the workflow service. Do not embed the runtime in Flutter.
  • Never ship a service-role key to a client.
  • Pin the runtime at start. Do not move an in-flight graph run onto WorkflowRuntime.
  • Seed versions in reviewed migrations. create_run does not register workflows.

Operations

  • Give every replica a unique workerId.
  • Keep heartbeats shorter than leases.
  • Treat blocked as healthy wait, not a stuck run.
  • Use readiness, dead letters, and the inspector before writing ad-hoc SQL.

Tests

  • Use WorkflowTestHarness for deterministic replay tests.
  • Cover restart at every durable await, not only the happy path.
  • Keep chaos, soak, and PostgreSQL campaigns in vyuh_workflow_testkit.

See Also