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, notFuture.wait. - Attach a
WorkflowDocumentwhen 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_rundoes not register workflows.
Operations
- Give every replica a unique
workerId. - Keep heartbeats shorter than leases.
- Treat
blockedas healthy wait, not a stuck run. - Use readiness, dead letters, and the inspector before writing ad-hoc SQL.
Tests
- Use
WorkflowTestHarnessfor deterministic replay tests. - Cover restart at every durable await, not only the happy path.
- Keep chaos, soak, and PostgreSQL campaigns in
vyuh_workflow_testkit.