Back to Blog Series
Part 6: Execution RuntimeStep 6 of 15InngestEvent-DrivenRuntime

Execution Engine: Event-Driven Workflow Processing with Inngest

How I execute Fluxo workflows with durable events, node-level channels, topological planning, and strict failure accounting.

Why this part is here in the storyline

Follow the event-driven engine that plans, runs, and accounts for each workflow execution.

Artem Moshnin, Lead Software EngineerFebruary 18, 202615 min
Series Progress6/15

Fluxo workflows are graphs, but users experience outcomes: a message sent, a row written, a document generated. The execution engine is the layer that turns a saved graph into a durable, observable process.

I built the runtime with three non-negotiables:

  • Durability. If the server restarts or a provider fails, work should resume instead of disappearing.
  • Determinism. The same graph should behave the same way, with predictable ordering and repeatable results.
  • Debuggability. When something fails, you should be able to explain it from recorded data, not guess.
Section 1

The execution model

#the-execution-model

Each workflow run starts as an event and becomes an Execution record. I used Inngest as the orchestration backbone because it gives durable function semantics and retry behavior without me building and operating a queue platform from scratch.

At the start of a run, Fluxo persists an Execution row with:

  • status (RUNNING, SUCCESS, FAILED)
  • inngestEventId
  • startedAt, completedAt
  • output payload snapshot
  • captured error and stack

Before any node executes, Fluxo plans the graph. Planning means topologically sorting nodes so each node runs only after its dependencies are satisfied. That keeps behavior deterministic and also enables parallelism when branches are independent.

Section 2

Node execution contract

#node-execution-contract

Every node type resolves through a typed executor registry. This design forces completeness: if a node exists in the product, it must have a runtime executor and a known data contract.

Runtime context carries accumulated outputs. Node executors read from context and write results back using stable paths and variable aliases. That single mechanism powers multiple features:

  • Template interpolation can reference upstream data reliably.
  • Analytics can attribute failures and latency to specific nodes.
  • Human Review can assemble content and context from the right upstream steps.
Section 3

Failure and observability strategy

#failure-and-observability-strategy

Failures are normal in automation: rate limits, credential mistakes, timeouts, malformed payloads. The difference between a toy and a production system is how failures are recorded and how recoverable they are.

When a node fails, Fluxo persists structured node-level error metadata into execution output:

  • node id, name, type
  • normalized message and optional stack
  • occurrence timestamp

This gives users actionable diagnostics and gives analytics the raw material to rank recurring failures and identify fragile integrations.

Section 4

Trigger dispatch architecture

#trigger-dispatch-architecture

Triggers are how workflows start, and triggers have different reliability needs. I separated trigger dispatch from workflow execution so each trigger can have its own polling and validation lifecycle:

  • schedule dispatcher checks cronExpression + timezone due windows
  • webhook dispatcher accepts payload/headers/method metadata
  • email trigger poller reads Gmail/IMAP state and last UID/date
  • RSS poller tracks lastItemGuid per workflow+node
  • file watcher poller tracks prior file state and change diffs

Each dispatcher emits execution events with stable id strategies to reduce duplicates and preserve traceability. In an event-driven system, you assume at-least-once semantics and then make duplicates safe.

Section 5

Plan enforcement in runtime, not just UI

#plan-enforcement-in-runtime-not-just-ui

The UI is advisory. The backend is enforcement. Before execution starts, Fluxo re-checks subscription constraints server-side:

  • workflow active state
  • execution quota
  • tier node eligibility
  • node count limit

This prevents bypasses and keeps behavior consistent no matter where the request originates.

Section 6

Background operations that keep the system healthy

#background-operations-that-keep-the-system-healthy

Beyond running graphs, the engine also runs operational lifecycle tasks:

  • review reminders and digests
  • prompt-learning suggestion generation windows
  • workflow version retention cleanup by tier
  • webhook fan-out dispatch for review lifecycle events

The engine is not only "run this graph". It is lifecycle management around that graph.

Section 7

Why Inngest was the right fit

#why-inngest-was-the-right-fit

I needed durable functions with clear event semantics and reliable retries without building a queue platform. Inngest let me keep execution logic in TypeScript while still shipping production-grade background orchestration.

That balance let me spend engineering effort on Fluxo’s differentiators: review governance, prompt learning, and agency-grade controls.