Skip to content
Ironflow is pre-1.0: APIs can change between releases. Pin a version. What is ready →

Comparison

Comparison set reviewed: October 2026. Existing vendor details were last verified in September 2026. Please file an issue if anything below is out of date.

Every comparison below answers the same question: where does the product start?

Workflow steps join the history only when recording is enabled on the function. Recording is off by default.

The starting point determines what each platform records and how you query it. Ironflow starts from the recorded fact: domain events and recorded workflow steps share a history. Akka SDK and Marten + Wolverine also combine event sourcing with durable processes, so the useful question is whether domain and execution history share an entity timeline or are linked across components.


FeatureIronflowTemporalInngestHatchetRestateKurrentAkka SDKMarten + Wolverine
Starting pointRecorded factWorkflowFunction triggerDurable taskStateful serviceEvent streamStateful componentEvent-sourced .NET application + durable messaging
ArchitectureSingle binary (embedded NATS)Cluster (server + DB + UI; ES/OpenSearch optional)Managed cloud, or self-hosted server + RedisServer + PostgreSQL (RabbitMQ optional)Single binary; HA cluster (GA)Server (clustering Enterprise-only from 26.2)SDK + Akka runtime; cloud or self-managedTwo .NET libraries + PostgreSQL
Domain events + execution historySame recorded history when step recording is enabledWorkflow history; domain events elsewhereTrigger events and runs stored separatelyExecution event log; domain events elsewhereExecution journal; mutable object stateDomain events onlyEntity journals and workflow state are distinct sourcesMarten event streams and Wolverine message/saga state are distinct
Local developmentironflow servetemporal server start-devnpx inngest-cli devHatchet Lite or embedded modeSingle binaryDockerJava/Maven + Akka CLI; local runtime.NET app + PostgreSQL
ExecutionPush (HTTP) and pull (HTTP polling, or an opt-in ConnectRPC streaming worker)Pull (gRPC)Push (HTTP) and Connect (WebSocket workers)Workers (bidirectional gRPC stream)Push (HTTP/2, Lambda)None built inDurable workflows and consumersDurable handlers, messages, and sagas
State storeSQLite / PostgreSQLMySQL / PostgreSQL / CassandraSQLite / PostgreSQL + Redis (self-host) or managedPostgreSQLEmbedded RocksDB + replicated logEvent storeEvent journal + workflow statePostgreSQL event store + message persistence

Authorization policy. The OPA claim is exact: embedded OPA engine, Rego v1, Envoy ext_authz input. Ironflow runs organization authorization policy as Rego on that engine. The Rego layer only denies, on top of role-based access. Ironflow embeds the OPA Go library and runs no OPA server. This page does not compare the access control of the other products. See Authorization policy sets.


Temporal starts from the workflow. Ironflow starts from the recorded fact. Temporal persists workflow history, while domain events generally live in another system. With recording enabled, Ironflow puts completed steps and domain events in one entity timeline, so “what happened to order-123?” can include both.

Temporal is the gold standard for durable execution at enterprise scale. If you need millions of concurrent workflows across a distributed cluster, Temporal is battle-tested.

Where Ironflow differs: Temporal treats workflows and events as separate concerns. You can emit signals and queries, but the workflow history and your domain events live in different systems. In Ironflow, with recording enabled, they’re the same history — which is why history navigation (time-travel debugging), history correction (hot patching), and unified entity timelines work out of the box.

IronflowTemporal
Setupironflow servetemporal server start-dev (in-memory; --db-filename for SQLite) or self-hosted cluster
Unified historyEvents + execution in one timelineWorkflow history only
DebuggingHistory navigation, correction, editingReplay-based, Web UI
Scale modelSingle node (SQLite) or multi-node cluster (Postgres + external NATS)Distributed cluster (millions)

Choose Temporal if you need massive distributed scale with proven enterprise support, or its Durable AI integrations (OpenAI Agents SDK, LangGraph, Pydantic AI). Choose Ironflow if you want events and recorded execution in one history and the tools to correct that history in production.


Inngest starts from the function trigger. Events kick off workflows and are retained for a plan-dependent window (hours to days) so you can inspect and replay them — but they are execution inputs, not a domain history. In Ironflow, events are recorded facts that stay until you prune or delete them. Recorded workflow steps are the same kind of fact. The trigger and the execution live in the same history. Inngest’s event store and run store are two systems sharing a product, not one unified history.

Inngest delivers excellent developer experience for serverless workflows. If you’re building on Vercel/Next.js and want managed infrastructure, Inngest is polished. Self-hosting is supported (SSPL with an Apache-2.0 future grant; SQLite or Postgres plus Redis), and the Connect mode adds persistent WebSocket workers alongside push.

Where Ironflow differs: Inngest treats events as triggers with a retention window — queryable via Insights, replayable in bulk, then gone. There are no entity streams, no projections to derive, no entity timeline to browse. Ironflow treats events as permanent facts that power projections, entity streams, and time-travel.

IronflowInngest
EventsRecorded facts, kept until you prune or delete themTriggers retained for a plan window (1h–3d lookback)
Event sourcingNative (entity streams, projections)Not available
HostingSelf-hosted (single binary)Managed cloud or self-hosted (SSPL)
Execution modesPush + PullPush + Connect (WebSocket workers)

Choose Inngest if you want a managed cloud service with zero ops for serverless functions. Choose Ironflow if you want your events to be permanent history, not disposable triggers.


Hatchet starts from the durable task. Workers hold a gRPC stream to the engine, PostgreSQL is the source of truth, every checkpoint persists, and the dashboard replays the execution log. It’s a sharper Temporal: same shape, simpler ops, MIT-only. But the durability is execution-shaped, not domain-shaped — if you want your domain events and your workflow steps in the same history, Hatchet keeps them in different stores.

Hatchet is the cleanest “Temporal but Postgres-only” pitch in the market. If your team already runs Postgres, doesn’t need a separate broker, and wants a familiar workflow-engine model, Hatchet is sharp. Its new embedded mode bundles the engine and Postgres in-process for local dev (stable in Go, early beta in TypeScript and Python).

Where Ironflow differs: Hatchet’s “durable” means the execution event log — task started, task completed, retry attempted, plus durable event waits scoped to a run. Ironflow’s “durable” means the recorded fact — your domain events and your workflow steps in one continuous history. That’s why entity timelines, projections, and time-travel across workflows + events all work in Ironflow and don’t exist in Hatchet.

IronflowHatchet
StorageSQLite (dev) / Postgres (prod) + embedded NATSPostgreSQL (source of truth and queue; RabbitMQ optional)
Durability scopeDomain events + execution steps in one historyExecution event log only
Execution modesPush + PullWorkers over bidirectional gRPC only
Agent surfaceagent() handler with ctx-injected tool / llm / approve / memory / spawn + MCP server (ironflow mcp)Generic tasks; child tasks as tools, compatible with Claude / OpenAI agent SDKs (no agent API)
History toolsTime-travel, hot patching, scoped injection, TUI/DAPDashboard replay

Choose Hatchet if you want a sharper Temporal with Postgres-only operational simplicity for plain task workloads. Choose Ironflow if you want events and execution in one history, agent-native primitives, and history navigation/correction built in.


Kurrent starts from the event stream. Ironflow starts from the recorded fact. Kurrent records your data changes — and now offers SQL over them (Queries UI, Flight SQL) and atomic multi-stream appends. But your workflow execution, your authorization decisions, your debugging sessions will always live somewhere else. In Ironflow, those are all recorded facts in the same history (workflow steps when recording is enabled). Cross-concern time-travel and an inspectable history emerge from that unification.

Kurrent is the pioneer of event sourcing databases. If you need a dedicated, high-performance event store with mature subscription APIs, KurrentDB is the original. Note the license shift: it is source-available (Kurrent License v1), and from 26.2 multi-node clustering, read-only replicas, archiving and encryption-at-rest are Enterprise-only, while single-node production stays free.

Where Ironflow differs: Kurrent stores your domain events but doesn’t execute workflows. Its answer to sagas is multi-stream atomic append; for durable execution you need a separate orchestrator (Temporal, MassTransit, etc.). In Ironflow, workflow steps and domain events are both recorded facts in the same history — so you can see everything that happened to an entity in one view.

IronflowKurrent
Event storageBuilt-in (entity streams)Dedicated event store
Workflow executionBuilt-in (durable, memoized)Not available (need separate tool)
ProjectionsBuilt-in (managed + external)JS projections (V1 maintenance, V2 experimental); SQL is query-only and license-gated
Unified historyEvents + execution togetherEvents only

Choose Kurrent if you need a dedicated event store with mature subscription APIs and are fine with clustering behind an Enterprise license. Choose Ironflow if you want event sourcing and workflow execution unified in one history.


Akka is the closest comparison here for a Java team building an event-sourced application. Its Event Sourced Entities keep domain events in a journal; Workflows persist step progress and resume after failures. Consumers and Views can react to entity events or workflow state changes. Akka also supports brokerless pub/sub.

The distinction is the record you inspect. Akka’s entity event journals and workflow state are separate component sources; a View can consume either. Ironflow records domain events and, when enabled, workflow steps in one history that its debugging tools can navigate and correct. Akka offers a distributed runtime and managed deployment options; Ironflow offers a single server binary and Go, Node, and Python worker SDKs. Akka’s current releases require a production license key.

Choose Akka if your application is Java-first and you want event-sourced entities, durable workflows, and distributed deployment in one runtime. Choose Ironflow if you want the domain and recorded execution history on one entity timeline, including production history correction.


For .NET teams, Marten provides PostgreSQL-backed event streams and projections while Wolverine provides durable messaging, handlers, and sagas. Their integration includes transactional inbox/outbox support, and the documentation shows an event-sourced process manager. This is a serious alternative if an application already runs on .NET and PostgreSQL.

The integration coordinates two libraries over PostgreSQL. Marten’s domain stream and Wolverine’s message or saga state remain distinct records. Ironflow puts recorded steps and domain events in one history and supplies a server, dashboard, and history correction tools around it.

Choose Marten + Wolverine if you want event sourcing and durable processes inside a .NET application with PostgreSQL. Choose Ironflow if one inspectable history across domain events and recorded execution is the deciding requirement.


Kafka remains a useful comparison for high-throughput streaming. It is a topic log and processing ecosystem rather than a durable workflow and domain event-sourcing platform, so it is outside the main matrix. Ironflow’s stack fit guide recommends Kafka or NATS directly for high-throughput streaming.


Restate starts from the distributed state machine. Ironflow starts from the recorded fact. Restate provides durable execution with an embedded state store and a SQL-queryable journal, but that journal is retention-bounded (24h by default) and events and execution remain separate concerns. In Ironflow, they’re the same history.

Restate offers durable execution with an elegant virtual object model, shipped as a single binary (BSL 1.1) with GA multi-node clusters, Restate Cloud, and Vercel AI SDK / OpenAI / LangChain agent integrations. If you’re building distributed state machines with strong consistency, Restate is innovative.

Where Ironflow differs: Restate focuses on durable execution and state management but doesn’t provide event sourcing, projections, or unified entity timelines. Ironflow’s recorded-fact foundation means all of these emerge naturally.

IronflowRestate
Event sourcingBuilt-inNot available
ProjectionsBuilt-inNot available
State modelEvent-sourced (derived from history)Virtual objects (mutable state)
Unified historyEvents + execution in one timelineExecution journal only (24h default retention)

Choose Restate if you want distributed virtual objects with strong consistency guarantees. Choose Ironflow if you want execution and events in one continuous history.


The products above draw the boundary in different places. Restate’s journal expires after 24 hours by default. Inngest retains trigger events for a plan window. Kurrent keeps domain events but does not execute workflows. Akka and Marten + Wolverine cover both domain events and durable processes, but expose separate entity and execution records. With step recording enabled, Ironflow places a domain event and a completed step in the same history.

  • Ask “what happened to order-123” and get events, steps, and projections in one answer
  • Projections and entity streams can derive from the same recorded history that workflows write to
  • Nothing to join, sync, or reconcile across an event store and an orchestrator

2. History You Can Edit (The “Workflow DVR”)

Section titled “2. History You Can Edit (The “Workflow DVR”)”

Competitors added replay and introspection this year. None added correction. With recording enabled, every step is a recorded fact, so Ironflow can change the record and continue from it:

  • History Correction (hot patching): Edit a failed step’s output in production and resume execution.
  • History Navigation (time-travel debugging): Scrub through any execution frame-by-frame.
  • History Editing (scoped injection): Pause a running workflow, modify step data, resume.
  • TUI Debugger: Step through production runs in your terminal.
  • DAP Support: Attach VS Code to a production run ID.

Restate is push-only; Temporal and Hatchet are worker-only; Inngest added Connect for persistent workers next to push. Ironflow runs both modes against the same history, so a serverless push function and a long-running pull worker write to the same entity timeline.

  • Push Mode: Best for Next.js, Lambda, and serverless. Ironflow calls you.
  • Pull Mode: Best for AI/ML, video processing, and long-running tasks. Your worker polls Ironflow over HTTP, or holds an opt-in ConnectRPC stream.

Single-binary local dev (embedded NATS JetStream + SQLite) is still there. Restate ships a single binary too, while Hatchet and Inngest have streamlined local development.


import { createFunction } from "@ironflow/node";
const processOrder = createFunction(
{
id: "process-order",
triggers: [{ event: "order.placed" }],
recording: true, // Every step becomes a recorded fact
},
async ({ event, step }) => {
const payment = await step.run("charge", () => stripe.charge(event.data.total));
await step.sleep("wait-for-inventory", "5m");
return { success: true };
}
);
func OrderWorkflow(ctx workflow.Context, order Order) (OrderResult, error) {
options := workflow.ActivityOptions{ StartToCloseTimeout: time.Minute }
ctx = workflow.WithActivityOptions(ctx, options)
var result ChargeResult
err := workflow.ExecuteActivity(ctx, ChargeActivity, order).Get(ctx, &result)
if err != nil { return nil, err }
workflow.Sleep(ctx, 5*time.Minute)
return OrderResult{Success: true}, nil
}

  • You want one history, not many: Events, workflow steps, and projections in one unified timeline per entity.
  • You need to fix a production run, not just replay it: Hot patching, scoped injection, and time-travel are correction tools, not viewers.
  • You need an inspectable history: With recording enabled, the engine writes the audit trail, so it is not a separate layer to build. Its rows are best effort under load.
  • You are event-sourcing already: Entity streams, projections, and upcasters are native, and the workflow that reacts to an event lands in the same stream.
  • You are building an AI agent: agent() handlers with approve / memory / spawn write to the same history as everything else, so an agent run is debuggable like any other run.
  • You are on the edge: Single Go binary for limited-resource environments.

Ironflow publishes no benchmark numbers. The in-tree bench suite (make bench + k6 load tests) is how you measure on your own hardware. See Benchmarks for methodology and how to reproduce.

MetricIronflowTemporalInngestHatchetRestate
Setup Time<1 minute (single binary)Minutes (start-dev); hours for a self-hosted clusterMinutes (dev server)Minutes (embedded mode or Docker)Minutes (single binary)
Boot TimeNot publishedNot publishedN/A~25ms p95 dispatch (server boot not published)Not published
Load-test latencyNot publishedNot directly comparableCloud-managedNot publishedNot published
Throughput (vendor-published)Not published — depends on hardware + storage backend450k actions/s (Cloud)Not published10k tasks/s load test; ~25ms p95 dispatch84k actions/s, 3-node bench (v1.2)
Memory FootprintNot publishedNot publishedN/A (Cloud)Not published~1.5 GiB minimal, ~4.75 GiB default (documented)

Ironflow’s Continuous History model puts domain events and recorded execution in one history, with tools to navigate and correct it.

Temporal, Inngest, Hatchet, and Restate primarily record execution. Kurrent primarily records domain events. Akka SDK and Marten + Wolverine now cover both sides and belong in any serious comparison; their entity and process histories remain distinct. Ironflow’s case rests on the shared timeline and its history navigation and correction tools.