Skip to content

Production Patterns

This guide focuses on the practical choices that make Orchestrix flows safer and clearer in production.

The goal is not to make every flow complex. The goal is to add the right safeguards to the workflows that perform meaningful side effects.

Distributed idempotency

If your application runs on multiple instances, duplicated execution protection should not rely on in-memory state alone.

Use a distributed idempotency store when duplicate execution could be harmful.

Redis store

ts
import { createClient } from "redis";
import { create, redisIdempotencyStore } from "@eddiecbrl/orchestrix";

const redisClient = createClient({ url: "redis://localhost:6379" });
await redisClient.connect();

const store = redisIdempotencyStore(redisClient);
const flow = create("production-flow", { idempotency: store });

Input validation

Validate input before any side effects start.

ts
import { z } from "zod";

const inputSchema = z.object({
  userId: z.string().uuid(),
  amount: z.number().positive(),
});

const flow = create("validated-flow", { schema: inputSchema });

This reduces ambiguity and makes failure happen at the safest moment: before the workflow begins real work.

Timeouts on external steps

Any step that touches the network should usually define a timeout.

ts
flow.step("call-provider", async () => {
  // ...
}, {
  timeoutMs: 5000,
  retries: 3,
  backoffFactor: "exponential"
});

Without timeouts, hung dependencies can make failures slow and hard to diagnose.

Context discipline

Keep the execution context small and intentional.

Prefer storing:

  • IDs
  • references
  • derived values needed later

Avoid storing:

  • very large objects
  • secrets unless you fully control logging and handling
  • data that should really live in durable storage

Testing workflows

Production confidence comes from testing both happy paths and failure paths.

Test step behavior

Export step functions when it helps you test the business logic in isolation.

Test full-flow behavior

Test:

  • successful execution
  • retry behavior
  • compensation order
  • idempotency behavior
  • timeout behavior

Long-running workflow boundaries

Orchestrix is a strong fit for workflows that complete within the lifetime of a process, request, or background job.

If a workflow needs to wait for hours or days, it is usually better to split it into multiple flows triggered by events rather than keeping one logical execution open forever.

Operational recommendations

  • Use idempotency for charge, create, reserve, and webhook flows.
  • Validate input before step execution.
  • Put timeouts on external calls.
  • Add compensation for meaningful side effects.
  • Use hooks for logs, metrics, and alerts.
  • Inspect and persist FlowResult for critical flows when useful.

Released under the MIT License.