Jaal
It's always the compiler

Write with basic constructs like loops and if-else.
Get an execution graph you can edit.

The compiler and the transpiler turn plain Java or Python into a durable, parallel execution graph: run it on the Java runtime, or transpile it to C++ or Rust (in progress). Change the graph and your code changes with it. Every step recorded, every run rewindable. No workflow SDK to learn, no determinism rules to follow, no rewrite between the demo and the real thing.

Java Python TypeScript Go C# Jaal IDE checked as you type, refused with the fix compiler IR one graph: durable, parallel Java runtime C++ executable Rust you write in it runs as
supportedin progressnot started

Easy to build, or built to scale. Pick both.

At one end, tools that make building easy. At the other, platforms that keep what you built running at scale. Both ends have very good products. In between lives the part nobody puts in a demo.

Easy to build

A demo by Friday

Drag a node, write a prompt, add a decorator. Good company here: n8n, LangGraph, the AI app builders.

Then someone says "production".

Everything in the middle

Where demos get rewritten

The workflow SDK, the determinism rules, the retries, the sagas by hand, the glue between the two.

Most teams stay here longer than they planned.

Scaling what's built

Durable, versioned, battle-tested

Good company here too: Temporal, Ray, Step Functions.

Bring the rewrite with you.

Jaal covers all three, with one compiler. Write it like a prototype, run it like production: the same file, from the first line to the 2 a.m. crash it shrugs off. Nothing to rewrite in between.

Your agent writes the logic. Who builds the infrastructure?

A coding agent will write your business logic before lunch. The infrastructure around it is a different job: it is not a prompt, it is a platform.

An agent does this well

The business logic

Price the order, check the policy, call the model, write the summary. Ask, review, ship.

A platform has to do this

Everything around it

Durability, retries, parallel work, compensation when a step fails, versions that hold under running work, deployment, replay. Infrastructure a model writes is infrastructure you now review, test and keep running at 2 a.m.

Let the agent write the logic. The compiler derives the rest: the same way every time, checked before it runs.

Derive, not vibe

You write the intent as plain code, or ask the assistant to write it. Jaal derives the graph from it: what depends on what, what runs together, what is recorded. You never draw the graph and never keep it in sync; when you want it different, you change the code, or you change the graph and the code follows.

built

1. Write the intent

Flight f = flight.hold(trip);
Hotel h = hotel.hold(trip);
Car c = car.hold(trip);
Paid p = pay.charge(f, h, c);

Plain code, written top to bottom. No futures, no fan-out construct.

built

2. See what was derived

flight hotel car pay

The three holds do not depend on each other, so the compiler runs them together; the payment waits for all three.

built

3. Enforce an order where you want one

Flight f;
Hotel h;
{{
    f = flight.hold(trip);
    h = hotel.hold(trip);
}}
Car c = car.hold(trip);

Pick flight and hotel on the graph, choose Run these in order, and the code gains a {{ }} block: a sequence inside the flow, everything else still as parallel as it can be. Nothing is reordered, the compiler checks the change before it is written, and one click undoes it.

Hot swap, graded by risk

Change a service while it runs. Jaal compares the new version with the old, tree against tree, grades the change from the lowest risk to the highest (same, bytes, surface, contract), and offers the swap that fits. The grade is derived, never typed in.

higher risk · router planned

1. A new endpoint contract

The contract itself changes: what goes in or comes out, even one optional field. That is a new endpoint version. Callers move to it only when it is promoted, and a router endpoint in front can shift traffic by weight or adapt between the old model and the new. Graded contract.

lower risk · built

2. New code inside the same type contract

The contract stays as it is; only the code behind it changes. The endpoint takes the new code in place: the next step of every conversation, new or already running, goes through it, with no restart. A change to the contract, the dependencies or the container is refused by name, so this swap cannot break a caller. Graded bytes or surface.

At a glance

One topic, asked precisely. Where others have it too, they get the tick.

From plain code to a durable, parallel system
JaalTemporalRestateInngestGolemResonateDBOSHatchetTrigger.devConductorCadenceDapr WorkflowStep FunctionsLambda durableAzure DurableCloudflare WorkflowsVercel WorkflowPrefectAirflowLangGraphRay
Score, out of 2416½13½119½1381097109910½11½10½889999
Plain code: no workflow constructs to write (no activities, steps, decorators, DAGs, BPMN or JSON)✓✗1✗2✗3✗4✗5✗6✗7✗8✗9✗10✗11✗12✗13✗14✗15✗16✗17✗18✗19✗20
Independent calls run in parallel without futures, Promise.all or parallel nodes✓✗21✗22✗23✗24✗25✗26✗27✗28✗29✗30✗31✗32✗33✗34✗35✗36✗37✗38✗39
A version's identity is derived from its content, and running work stays on it✓✗40✓41✗42✓43✗44✓✓45✗46✗47✓48✓49✗50✓51✓52✗53
After a crash, it resumes from the last state: no replay of the code from the start✓✗54✗55✗56✓57✗58✗59✗60✗61✓✗62✗63✓64✗65✗66✗67✗68✓69
Compensation built in, not a saga you hand-write✓✗70✗71✓✓✗72✗73✗74✓✗75✓
The execution graph is drawn from the code, and editing the graph rewrites the code✓
A deploy that would break the contract is refused by the platform, by name✓✓76✗77✗78
Compensation declared by the called service; the caller writes no undo code✓✗79✓80✗81✓82
A call to another service reads as a plain method call: no stubs, run(), invoke or step wrappers✓✓83✓84✗85✓86✗87✓88✗89✗90✗91✓92✗93✗94✗95✓96✗97✓98✓99✗100✓101✗102
A streamed response cut by a crash continues where it left off: no tokens regeneratedWIP103✓104✓105✓106✗107✓108✓109✓110
Concurrency safety proven by a compiler before the run, not by lint rules or run-time checks✓✓111✗112✗113✗114✗115✗116✓117✓118✗119✗120
Non-deterministic calls (clock, random, any library) recorded automatically: no determinism rules✓✓121✗122✗123✓✗124✗125✗126✗127✗128✗129✗130✗131✓132✗133
A conversation already running finishes on the new code, with no version markers in code✓✓134✗135✓✓136✗137✗138✗139✓140✓141✗142✓143✓144✗145✓146✓147
Runtime out of the box: engine, process management and scaling ship with it; no server, worker fleet and database to assemble✓148✓149✓150✓151✓✓152✓153✓154✓155✓156✗157✗158✓✓✓✓✓159✓160✗161✓162✓163
New code swapped into running work in place, no side-by-side deployment✓✓✓164✓✓✗165✗166✗167✓✓✗168✓169✓✗170✓✓
Running work stays on the version it started on when new code is deployed✓✓✓✗171✓✓✓✓✗172✗173✓✓174✓175✓✓176✗177
Execution history is an append-only log✓✓✓✓✗178✓✓✓✓✓✓✓179
Languages you write the workflow in
Write the workflow itself in Java✓✓✓✓180✗181✓182✓✗183✗184✓185✓✓✓186✓✓✗187✗188✗189✓190✓191✓192
Write the workflow itself in Python✗193✓✓✓✗194✓✓✓✓195✓196✓✓✓197✓✓✓198✓199✓✓✓✓
Write the workflow itself in TypeScript✗200✓✓✓✓✓✓✓✓✓201✗202✓✓203✓✓✓✓✗204✗205✓✗206
Write the workflow itself in Go✗207✓✓✓✓208✓209✓✓✗210✓211✓✓✓212✓✗213✗214✗215✗216✓217✓218✗219
Write the workflow itself in Rust✗220✓✓✗221✓✓222✗223✗224✗225✓226✗227✗228✓229✗230✗231✗232✗233✗234✗235✗236✗237
Write the workflow itself in C/C++✗238✗239✗240✗241✗242✗243✗244✗245✗246✗247✗248✗249✓250✗251✗252✗253✗254✗255✗256✗257✓258
Write the workflow itself in C#/.NET✗259✓✗260✗261✗262✗263✗264✗265✗266✓267✗268✓✓269✓✓✗270✗271✗272✗273✗274✗275

✓ documented (1 point)   ✓ partly, see its note (½)   blank: not found in its docs (½)   ✗ its own docs show it is not there, see its note (0). Checked against each product's documentation on 26 October 2026. Every Jaal tick is built today; WIP and the red Jaal marks are not built yet (0).

The notes behind each grey and red mark (275)
  1. Temporal: You write deterministic Workflows plus Activities with its SDK. source
  2. Restate: You write handlers, virtual objects and workflows, wrapping work in ctx.run. source
  3. Inngest: You write steps with step.run and the other step functions. source
  4. Golem: Durability needs no wrappers, but parallel work is written with worker clients, create_promise and await_promise. source
  5. Resonate: You write generator functions that call context.run. source
  6. DBOS: You annotate workflows and steps. source
  7. Hatchet: You define tasks, DAG workflows and durable tasks. source
  8. Trigger.dev: You define tasks with task() and call triggerAndWait. source
  9. Conductor: Workflows are JSON definitions. source
  10. Cadence: You write deterministic workflows plus activities with its SDK. source
  11. Dapr Workflow: You write workflows plus activities with its SDK. source
  12. Step Functions: Workflows are JSON state machines (Amazon States Language). source
  13. Lambda durable: You write DurableContext steps, waits and invokes. source
  14. Azure Durable: You write orchestrator, activity and entity functions. source
  15. Cloudflare Workflows: You write step.do and step.sleep calls. source
  16. Vercel Workflow: You mark code with the "use workflow" and "use step" directives. source
  17. Prefect: You decorate code with @flow and @task. source
  18. Airflow: You define Python DAGs. source
  19. LangGraph: You build a graph of nodes and edges, or use @entrypoint and @task. source
  20. Ray: You write @ray.remote tasks and actors. source
  21. Temporal: Parallel work is written with futures, Promise.all or asyncio.gather. source
  22. Restate: Parallel work is written with DurableFuture.all or Select. source
  23. Inngest: Parallel steps are written with Promise.all. source
  24. Golem: Parallel work fans out to child agents explicitly. source
  25. Resonate: Parallel work is written with beginRun / beginRpc futures. source
  26. DBOS: Parallel work goes through durable queues. source
  27. Hatchet: Parallel work is declared as DAG dependencies or child tasks. source
  28. Trigger.dev: Parallel work is written with batchTriggerAndWait. source
  29. Conductor: Parallel work is a FORK_JOIN declared in the definition. source
  30. Dapr Workflow: Parallel work is written with when_all / Task.WhenAll. source
  31. Step Functions: Parallel work is a Parallel or Map state. source
  32. Lambda durable: Parallel work is written with context.parallel or context.map. source
  33. Azure Durable: Parallel work is an explicit fan-out / fan-in (Task.WhenAll). source
  34. Cloudflare Workflows: Parallel steps are written with Promise.all. source
  35. Vercel Workflow: Parallel steps are written with Promise.all. source
  36. Prefect: Parallel work is written with .submit() and task runners. source
  37. Airflow: Parallel work is declared as DAG dependencies. source
  38. LangGraph: Parallel work is declared with fan-out edges and Send. source
  39. Ray: Parallel work is written with .remote() futures. source
  40. Temporal: A version is a Build ID supplied in the worker's deployment options. source
  41. Restate: Running requests stay on their version automatically, but a version is the endpoint you deploy and register, not derived from the code. source
  42. Inngest: There are no versions: a resumed run uses the current code. source
  43. Golem: Agents stay on their revision, but the docs do not say a revision is derived from content. source
  44. Resonate: A version is a developer option, 1 by default. source
  45. Trigger.dev: Each deploy makes a version and a run never changes version, but the identity is a date and counter. source
  46. Cadence: Changes are guarded with GetVersion markers the developer numbers. source
  47. Dapr Workflow: Versioning is by patching and developer-named workflow versions. source
  48. Step Functions: Executions stay on a published version, but publishing is explicit and the number is a counter. source
  49. Lambda durable: Executions can be pinned to a published version, but you publish and invoke it yourself. source
  50. Azure Durable: Orchestration versioning uses a version string the developer sets. source
  51. Vercel Workflow: Runs are pinned to the deployment that starts them, identified by deployment ID, not by content. source
  52. Airflow: With a Git bundle a run keeps its commit; the default local bundle has no versioning. source
  53. LangGraph: There are no versions: the latest graph applies to every thread. source
  54. Temporal: Recovery replays the workflow code against the event history. source
  55. Restate: Recovery is replay of the handler, skipping journaled steps. source
  56. Inngest: A run resumes by replaying the handler with saved step results. source
  57. Golem: Recovery replays the oplog; opt-in snapshots shorten the replay. source
  58. Resonate: After a crash, execution starts from the top of the function. source
  59. DBOS: An interrupted workflow is restarted by calling it again with its inputs. source
  60. Hatchet: The durable event log is replayed to rebuild state. source
  61. Trigger.dev: A retried task starts from the beginning, with cached subtask results. source
  62. Cadence: Workflow code is re-executed to rebuild state. source
  63. Dapr Workflow: On replay the workflow runs again from the beginning. source
  64. Step Functions: A failed run can be redriven from the failed step, by hand. source
  65. Lambda durable: On replay the code runs from the beginning, skipping completed checkpoints. source
  66. Azure Durable: The orchestrator re-executes the whole function from the start. source
  67. Cloudflare Workflows: Code outside steps runs again after hibernation. source
  68. Vercel Workflow: Workflow code is re-run, using the event log to reach its spot. source
  69. LangGraph: Graph API nodes re-run from the start of the interrupted node; the Functional API replays from the top. source
  70. Temporal: Compensation is a documented saga pattern written in workflow code. source
  71. Restate: Sagas are implemented in user code. source
  72. Dapr Workflow: Compensation is a documented pattern written in the workflow. source
  73. Step Functions: Compensation is a pattern built from Catch fields. source
  74. Azure Durable: Compensation is written in a catch block. source
  75. Vercel Workflow: Compensation is a saga recipe written in the workflow. source
  76. Restate: Registration refuses removed or renamed handlers, but checks no input or output types, and a flag overrides it. source
  77. Dapr Workflow: Changing a workflow's name, input or output deploys and can fail at runtime. source
  78. Azure Durable: An activity signature change deploys and can break orchestrators that use it. source
  79. Restate: Sagas are written in the calling handler, adding compensations step by step. source
  80. Golem: An operation carries its own undo, but the caller must open the transaction. source
  81. Conductor: The workflow author configures a failure workflow. source
  82. Prefect: A task declares its rollback hook, but the flow must open a transaction. source
  83. Temporal: The call reads like a function, but on a handle built first with proxyActivities in the workflow. source
  84. Restate: Calls go through a typed client taken from the context: ctx.serviceClient(...).handler(...). source
  85. Inngest: Another function is called through step.invoke with an ID and options. source
  86. Golem: Methods are called directly, on a client obtained first with get(...). source
  87. Resonate: Every durable call goes through ctx.run or ctx.rpc. source
  88. DBOS: A step is called as a plain function, but it is a step in the same program, not another service. source
  89. Hatchet: A child is spawned with a generic run() on a task object. source
  90. Trigger.dev: A child is called with triggerAndWait and returns a result wrapper to unwrap. source
  91. Conductor: Tasks are referenced by registered names in a JSON definition. source
  92. Cadence: Java calls a method on a stub made with newActivityStub; Go uses ExecuteActivity(ctx, fn). source
  93. Dapr Workflow: Activities are called through the context: CallActivityAsync and its kin. source
  94. Step Functions: Task states call services through a Resource ARN in JSON. source
  95. Lambda durable: Service calls are wrapped in steps on the DurableContext. source
  96. Azure Durable: The default is CallActivityAsync(nameof(...)); typed calls come from a source generator in preview. source
  97. Cloudflare Workflows: Work is written as step.do(name, fn). source
  98. Vercel Workflow: A step is called with a plain await, but it is a step in the same program, not another service. source
  99. Prefect: A task is called like a normal function, but it is a task in the same flow, not another service. source
  100. Airflow: TaskFlow calls look like functions but build DAG dependencies behind the scenes. source
  101. LangGraph: A @task call returns a future read with .result(); the Graph API is nodes and edges. source
  102. Ray: A remote function is called with .remote() and read with ray.get. source
  103. Jaal: Work in progress: the recorded stream and its resume point are designed, not built.
  104. Temporal: Workflow Streams (preview) resume a subscriber from its offset; a retried activity streams its events again. source
  105. Inngest: The browser can reattach, but a step that fails and retries streams fresh data. source
  106. DBOS: Writes survive a restart, but a retried step can write its output again. source
  107. Hatchet: Events published before a consumer starts are dropped; no resume is described. source
  108. Trigger.dev: A lost connection resumes from the last chunk; a task crash or retry is not covered. source
  109. Vercel Workflow: Clients reconnect from a start index; a step crashing mid-stream is not described. source
  110. LangGraph: A dropped connection resumes with Last-Event-ID; a server crash is not covered. source
  111. Temporal: An optional Go-only checker, workflowcheck, can help; other SDKs check at run time. source
  112. Resonate: Determinism is left to the author, with no static check. source
  113. DBOS: The only check is a run-time non-determinism error. source
  114. Trigger.dev: The docs tell developers which concurrent calls to avoid. source
  115. Cadence: Workflow code must use Cadence channels and selectors; no official checker. source
  116. Dapr Workflow: Determinism is a rule for authors, with no analyzer. source
  117. Lambda durable: A Go-only linter, durablelint, flags issues and can be silenced. source
  118. Azure Durable: A C#-only Roslyn analyzer warns at build time; its warnings can be suppressed. source
  119. Cloudflare Workflows: Concurrency over steps is written guidance only. source
  120. LangGraph: Conflicting parallel writes are refused only while the graph runs. source
  121. Temporal: Only in the TypeScript sandbox are Math.random and Date made deterministic; other effects must be Activities. source
  122. Restate: Non-deterministic work must be wrapped in run(). source
  123. Inngest: Non-deterministic logic must go inside step.run(). source
  124. Resonate: Non-deterministic calls go in a leaf function run via ctx.run. source
  125. DBOS: A workflow function must be deterministic. source
  126. Hatchet: Durable-task code must be deterministic; avoid clock and random reads. source
  127. Cadence: Workflow code must use Cadence APIs for time and must be deterministic. source
  128. Dapr Workflow: Workflow code must be deterministic. source
  129. Lambda durable: Every non-deterministic call must be wrapped in a step. source
  130. Azure Durable: Orchestrator code must not use time APIs or random values directly. source
  131. Cloudflare Workflows: Non-deterministic logic must go inside step.do. source
  132. Vercel Workflow: Math.random and Date are fixed automatically; any other effect must be a step. source
  133. LangGraph: Random numbers and clock reads must be kept inside tasks. source
  134. Temporal: Running workflows continue on new code only for replay-compatible changes; otherwise patching is needed. source
  135. Restate: Requests start and end on the same version. source
  136. Golem: An update replays the agent on the new revision, but must be triggered and falls back if replay diverges. source
  137. DBOS: Only workflows whose version matches the current application are recovered. source
  138. Trigger.dev: A run never changes version. source
  139. Conductor: Running executions keep the definition snapshot taken at start. source
  140. Cadence: Continues on new code only for compatible changes; otherwise GetVersion is needed. source
  141. Dapr Workflow: Continues on new code only while it stays deterministic; otherwise patching. source
  142. Step Functions: A redriven execution uses the same definition; an update needs a new execution. source
  143. Lambda durable: Unpinned executions continue only if steps are not changed in ways that break replay. source
  144. Azure Durable: Running orchestrations replay on new code; breaking changes need version branching. source
  145. Vercel Workflow: Runs are pinned to the deployment that starts them. source
  146. Airflow: Only with the unversioned local bundle do remaining tasks use the latest code. source
  147. LangGraph: Old threads resume on the new graph, but renames break them and changes need a version stamp. source
  148. Jaal: The host agent (process manager) and deploy are built; scaling by instances is ruled (10-24) but not built; you install Postgres.
  149. Temporal: You host and scale your own workers, even on Temporal Cloud; self-hosting adds a server cluster and a database. source
  150. Restate: The server is one binary with no database, but you deploy and run your own services. source
  151. Inngest: The engine is one binary or a cloud; your function code runs in your own app or host. source
  152. Resonate: One command with SQLite for development; Postgres and your own processes in production. source
  153. DBOS: A library in your app plus Postgres; you host and scale the app, or use DBOS Cloud. source
  154. Hatchet: An engine image plus Postgres, or Hatchet Cloud; you always run the workers. source
  155. Trigger.dev: Fully managed in its own cloud; self-hosting needs Postgres, Redis and runners. source
  156. Conductor: A server plus a database and a lock service, or Orkes Cloud; your task workers are yours. source
  157. Cadence: You run frontend, history and matching services plus Cassandra, MySQL or Postgres. source
  158. Dapr Workflow: You configure an actor state store and host the app (and a control plane on Kubernetes). source
  159. Vercel Workflow: Automatic on Vercel; elsewhere you supply a storage and queue backend such as Postgres. source
  160. Prefect: A server, a database and workers you run; Prefect Cloud's managed pools come close. source
  161. Airflow: You assemble a metadata database, scheduler, API server, DAG processor and executor. source
  162. LangGraph: Fully managed on LangSmith Cloud; self-hosting needs Postgres, Redis and a license. source
  163. Ray: Ships head, workers and an autoscaler, but you provision the cluster. source
  164. Restate: Forcing an existing registration is for local development; production versions are new deployments. source
  165. DBOS: Only workflows of the current version are recovered. source
  166. Trigger.dev: A run never changes version, even after new deploys. source
  167. Conductor: Running executions keep their start-time snapshot. source
  168. Step Functions: An updated definition needs a new execution. source
  169. Lambda durable: Unpinned executions may resume on changed code, but the docs recommend pinning. source
  170. Vercel Workflow: Workflows keep running on the deployment they were created on. source
  171. Inngest: A resumed run uses the current code. source
  172. Cadence: Running workflows replay on the updated code. source
  173. Dapr Workflow: Code updates apply to running instances. source
  174. Lambda durable: Executions are pinned when you invoke a version or alias. source
  175. Azure Durable: Version settings can match work to versions; by default code changes affect running work. source
  176. Airflow: With a versioned bundle a run keeps its code; the default local bundle does not. source
  177. LangGraph: The latest graph applies to every thread. source
  178. Resonate: Its blog describes un-sequenced promises rather than a sequenced log. source
  179. LangGraph: Checkpoints accumulate per thread, but are snapshots, not described as a log. source
  180. Inngest: Only a Kotlin SDK in its GitHub org, not on the SDK list; its Java example says coming soon. source
  181. Golem: Scala is listed; Java is not. source
  182. Resonate: Labelled pre-release. source
  183. Hatchet: Not on its language list. source
  184. Trigger.dev: Not on its language list. source
  185. Conductor: The SDK builds a JSON definition the server interprets; branches and loops are DSL tasks, not if and for. source
  186. Step Functions: CDK in this language only generates the JSON state machine; the workflow is Amazon States Language. source
  187. Cloudflare Workflows: Not on its language list. source
  188. Vercel Workflow: Not on its language list. source
  189. Prefect: Not on its language list. source
  190. Airflow: An experimental task SDK: task logic only; DAGs are always Python. source
  191. LangGraph: A community port only, not in the vendor's docs. source
  192. Ray: The Java APIs are experimental and community-supported. source
  193. Jaal: Not built yet. A Python orchestrator turns green once it compiles and runs end to end.
  194. Golem: Not on its language list. source
  195. Trigger.dev: A TypeScript task can run Python scripts; the task itself stays TypeScript. source
  196. Conductor: The SDK builds a JSON definition the server interprets; branches and loops are DSL tasks, not if and for. source
  197. Step Functions: CDK in this language only generates the JSON state machine; the workflow is Amazon States Language. source
  198. Cloudflare Workflows: Python Workflows are in open beta. source
  199. Vercel Workflow: Python is labelled beta. source
  200. Jaal: Not built yet.
  201. Conductor: The SDK builds a JSON definition the server interprets; branches and loops are DSL tasks, not if and for. source
  202. Cadence: Not on its language list. source
  203. Step Functions: CDK in this language only generates the JSON state machine; the workflow is Amazon States Language. source
  204. Prefect: Not on its language list. source
  205. Airflow: Not on its language list. source
  206. Ray: Not on its language list. source
  207. Jaal: Not built yet.
  208. Golem: Go is listed only in v1.6, still a release candidate. source
  209. Resonate: Labelled early release. source
  210. Trigger.dev: Not on its language list. source
  211. Conductor: The SDK builds a JSON definition the server interprets; branches and loops are DSL tasks, not if and for. source
  212. Step Functions: CDK in this language only generates the JSON state machine; the workflow is Amazon States Language. source
  213. Azure Durable: Not on its language list. source
  214. Cloudflare Workflows: Not on its language list. source
  215. Vercel Workflow: Not on its language list. source
  216. Prefect: Not on its language list. source
  217. Airflow: An experimental task SDK: task logic only; DAGs are always Python. source
  218. LangGraph: A community port only, not in the vendor's docs. source
  219. Ray: Not on its language list. source
  220. Jaal: Not built yet.
  221. Inngest: Not on its language list. source
  222. Resonate: Labelled early development. source
  223. DBOS: Not on its language list. source
  224. Hatchet: Not on its language list. source
  225. Trigger.dev: Not on its language list. source
  226. Conductor: The SDK builds a JSON definition the server interprets; branches and loops are DSL tasks, not if and for. source
  227. Cadence: Not on its language list. source
  228. Dapr Workflow: Not on its language list. source
  229. Step Functions: Only as Lambda tasks; the workflow is Amazon States Language. source
  230. Lambda durable: Not on its language list. source
  231. Azure Durable: Not on its language list. source
  232. Cloudflare Workflows: Not on its language list. source
  233. Vercel Workflow: Not on its language list. source
  234. Prefect: Not on its language list. source
  235. Airflow: Not on its language list. source
  236. LangGraph: Not on its language list. source
  237. Ray: Not on its language list. source
  238. Jaal: Not built yet.
  239. Temporal: Not on its language list. source
  240. Restate: Not on its language list. source
  241. Inngest: Not on its language list. source
  242. Golem: Not on its language list. source
  243. Resonate: Not on its language list. source
  244. DBOS: Not on its language list. source
  245. Hatchet: Not on its language list. source
  246. Trigger.dev: Not on its language list. source
  247. Conductor: Not on its language list. source
  248. Cadence: Not on its language list. source
  249. Dapr Workflow: Not on its language list. source
  250. Step Functions: Only as Lambda tasks; the workflow is Amazon States Language. source
  251. Lambda durable: Not on its language list. source
  252. Azure Durable: Not on its language list. source
  253. Cloudflare Workflows: Not on its language list. source
  254. Vercel Workflow: Not on its language list. source
  255. Prefect: Not on its language list. source
  256. Airflow: Not on its language list. source
  257. LangGraph: Not on its language list. source
  258. Ray: The C++ APIs are experimental and community-supported. source
  259. Jaal: Not built yet.
  260. Restate: Not on its language list. source
  261. Inngest: Not on its language list. source
  262. Golem: Not on its language list. source
  263. Resonate: Not on its language list. source
  264. DBOS: Not on its language list. source
  265. Hatchet: Not on its language list. source
  266. Trigger.dev: Not on its language list. source
  267. Conductor: The SDK builds a JSON definition the server interprets; branches and loops are DSL tasks, not if and for. source
  268. Cadence: Not on its language list. source
  269. Step Functions: CDK in this language only generates the JSON state machine; the workflow is Amazon States Language. source
  270. Cloudflare Workflows: Not on its language list. source
  271. Vercel Workflow: Not on its language list. source
  272. Prefect: Not on its language list. source
  273. Airflow: Not on its language list. source
  274. LangGraph: Not on its language list. source
  275. Ray: Not on its language list. source
The notes behind each grey and red mark (163)
  1. Temporal: You write deterministic Workflows plus Activities with its SDK. source
  2. Restate: You write handlers, virtual objects and workflows, wrapping work in ctx.run. source
  3. Inngest: You write steps with step.run and the other step functions. source
  4. Golem: Durability needs no wrappers, but parallel work is written with worker clients, create_promise and await_promise. source
  5. Resonate: You write generator functions that call context.run. source
  6. DBOS: You annotate workflows and steps. source
  7. Hatchet: You define tasks, DAG workflows and durable tasks. source
  8. Trigger.dev: You define tasks with task() and call triggerAndWait. source
  9. Conductor: Workflows are JSON definitions. source
  10. Cadence: You write deterministic workflows plus activities with its SDK. source
  11. Dapr Workflow: You write workflows plus activities with its SDK. source
  12. Step Functions: Workflows are JSON state machines (Amazon States Language). source
  13. Lambda durable: You write DurableContext steps, waits and invokes. source
  14. Azure Durable: You write orchestrator, activity and entity functions. source
  15. Cloudflare Workflows: You write step.do and step.sleep calls. source
  16. Vercel Workflow: You mark code with the "use workflow" and "use step" directives. source
  17. Prefect: You decorate code with @flow and @task. source
  18. Airflow: You define Python DAGs. source
  19. LangGraph: You build a graph of nodes and edges, or use @entrypoint and @task. source
  20. Ray: You write @ray.remote tasks and actors. source
  21. Temporal: Parallel work is written with futures, Promise.all or asyncio.gather. source
  22. Restate: Parallel work is written with DurableFuture.all or Select. source
  23. Inngest: Parallel steps are written with Promise.all. source
  24. Golem: Parallel work fans out to child agents explicitly. source
  25. Resonate: Parallel work is written with beginRun / beginRpc futures. source
  26. DBOS: Parallel work goes through durable queues. source
  27. Hatchet: Parallel work is declared as DAG dependencies or child tasks. source
  28. Trigger.dev: Parallel work is written with batchTriggerAndWait. source
  29. Conductor: Parallel work is a FORK_JOIN declared in the definition. source
  30. Dapr Workflow: Parallel work is written with when_all / Task.WhenAll. source
  31. Step Functions: Parallel work is a Parallel or Map state. source
  32. Lambda durable: Parallel work is written with context.parallel or context.map. source
  33. Azure Durable: Parallel work is an explicit fan-out / fan-in (Task.WhenAll). source
  34. Cloudflare Workflows: Parallel steps are written with Promise.all. source
  35. Vercel Workflow: Parallel steps are written with Promise.all. source
  36. Prefect: Parallel work is written with .submit() and task runners. source
  37. Airflow: Parallel work is declared as DAG dependencies. source
  38. LangGraph: Parallel work is declared with fan-out edges and Send. source
  39. Ray: Parallel work is written with .remote() futures. source
  40. Temporal: A version is a Build ID supplied in the worker's deployment options. source
  41. Restate: Running requests stay on their version automatically, but a version is the endpoint you deploy and register, not derived from the code. source
  42. Inngest: There are no versions: a resumed run uses the current code. source
  43. Golem: Agents stay on their revision, but the docs do not say a revision is derived from content. source
  44. Resonate: A version is a developer option, 1 by default. source
  45. Trigger.dev: Each deploy makes a version and a run never changes version, but the identity is a date and counter. source
  46. Cadence: Changes are guarded with GetVersion markers the developer numbers. source
  47. Dapr Workflow: Versioning is by patching and developer-named workflow versions. source
  48. Step Functions: Executions stay on a published version, but publishing is explicit and the number is a counter. source
  49. Lambda durable: Executions can be pinned to a published version, but you publish and invoke it yourself. source
  50. Azure Durable: Orchestration versioning uses a version string the developer sets. source
  51. Vercel Workflow: Runs are pinned to the deployment that starts them, identified by deployment ID, not by content. source
  52. Airflow: With a Git bundle a run keeps its commit; the default local bundle has no versioning. source
  53. LangGraph: There are no versions: the latest graph applies to every thread. source
  54. Temporal: Recovery replays the workflow code against the event history. source
  55. Restate: Recovery is replay of the handler, skipping journaled steps. source
  56. Inngest: A run resumes by replaying the handler with saved step results. source
  57. Golem: Recovery replays the oplog; opt-in snapshots shorten the replay. source
  58. Resonate: After a crash, execution starts from the top of the function. source
  59. DBOS: An interrupted workflow is restarted by calling it again with its inputs. source
  60. Hatchet: The durable event log is replayed to rebuild state. source
  61. Trigger.dev: A retried task starts from the beginning, with cached subtask results. source
  62. Cadence: Workflow code is re-executed to rebuild state. source
  63. Dapr Workflow: On replay the workflow runs again from the beginning. source
  64. Step Functions: A failed run can be redriven from the failed step, by hand. source
  65. Lambda durable: On replay the code runs from the beginning, skipping completed checkpoints. source
  66. Azure Durable: The orchestrator re-executes the whole function from the start. source
  67. Cloudflare Workflows: Code outside steps runs again after hibernation. source
  68. Vercel Workflow: Workflow code is re-run, using the event log to reach its spot. source
  69. LangGraph: Graph API nodes re-run from the start of the interrupted node; the Functional API replays from the top. source
  70. Temporal: Compensation is a documented saga pattern written in workflow code. source
  71. Restate: Sagas are implemented in user code. source
  72. Dapr Workflow: Compensation is a documented pattern written in the workflow. source
  73. Step Functions: Compensation is a pattern built from Catch fields. source
  74. Azure Durable: Compensation is written in a catch block. source
  75. Vercel Workflow: Compensation is a saga recipe written in the workflow. source
  76. Restate: Registration refuses removed or renamed handlers, but checks no input or output types, and a flag overrides it. source
  77. Dapr Workflow: Changing a workflow's name, input or output deploys and can fail at runtime. source
  78. Azure Durable: An activity signature change deploys and can break orchestrators that use it. source
  79. Restate: Sagas are written in the calling handler, adding compensations step by step. source
  80. Golem: An operation carries its own undo, but the caller must open the transaction. source
  81. Conductor: The workflow author configures a failure workflow. source
  82. Prefect: A task declares its rollback hook, but the flow must open a transaction. source
  83. Temporal: The call reads like a function, but on a handle built first with proxyActivities in the workflow. source
  84. Restate: Calls go through a typed client taken from the context: ctx.serviceClient(...).handler(...). source
  85. Inngest: Another function is called through step.invoke with an ID and options. source
  86. Golem: Methods are called directly, on a client obtained first with get(...). source
  87. Resonate: Every durable call goes through ctx.run or ctx.rpc. source
  88. DBOS: A step is called as a plain function, but it is a step in the same program, not another service. source
  89. Hatchet: A child is spawned with a generic run() on a task object. source
  90. Trigger.dev: A child is called with triggerAndWait and returns a result wrapper to unwrap. source
  91. Conductor: Tasks are referenced by registered names in a JSON definition. source
  92. Cadence: Java calls a method on a stub made with newActivityStub; Go uses ExecuteActivity(ctx, fn). source
  93. Dapr Workflow: Activities are called through the context: CallActivityAsync and its kin. source
  94. Step Functions: Task states call services through a Resource ARN in JSON. source
  95. Lambda durable: Service calls are wrapped in steps on the DurableContext. source
  96. Azure Durable: The default is CallActivityAsync(nameof(...)); typed calls come from a source generator in preview. source
  97. Cloudflare Workflows: Work is written as step.do(name, fn). source
  98. Vercel Workflow: A step is called with a plain await, but it is a step in the same program, not another service. source
  99. Prefect: A task is called like a normal function, but it is a task in the same flow, not another service. source
  100. Airflow: TaskFlow calls look like functions but build DAG dependencies behind the scenes. source
  101. LangGraph: A @task call returns a future read with .result(); the Graph API is nodes and edges. source
  102. Ray: A remote function is called with .remote() and read with ray.get. source
  103. Jaal: Work in progress: the recorded stream and its resume point are designed, not built.
  104. Temporal: Workflow Streams (preview) resume a subscriber from its offset; a retried activity streams its events again. source
  105. Inngest: The browser can reattach, but a step that fails and retries streams fresh data. source
  106. DBOS: Writes survive a restart, but a retried step can write its output again. source
  107. Hatchet: Events published before a consumer starts are dropped; no resume is described. source
  108. Trigger.dev: A lost connection resumes from the last chunk; a task crash or retry is not covered. source
  109. Vercel Workflow: Clients reconnect from a start index; a step crashing mid-stream is not described. source
  110. LangGraph: A dropped connection resumes with Last-Event-ID; a server crash is not covered. source
  111. Temporal: An optional Go-only checker, workflowcheck, can help; other SDKs check at run time. source
  112. Resonate: Determinism is left to the author, with no static check. source
  113. DBOS: The only check is a run-time non-determinism error. source
  114. Trigger.dev: The docs tell developers which concurrent calls to avoid. source
  115. Cadence: Workflow code must use Cadence channels and selectors; no official checker. source
  116. Dapr Workflow: Determinism is a rule for authors, with no analyzer. source
  117. Lambda durable: A Go-only linter, durablelint, flags issues and can be silenced. source
  118. Azure Durable: A C#-only Roslyn analyzer warns at build time; its warnings can be suppressed. source
  119. Cloudflare Workflows: Concurrency over steps is written guidance only. source
  120. LangGraph: Conflicting parallel writes are refused only while the graph runs. source
  121. Temporal: Only in the TypeScript sandbox are Math.random and Date made deterministic; other effects must be Activities. source
  122. Restate: Non-deterministic work must be wrapped in run(). source
  123. Inngest: Non-deterministic logic must go inside step.run(). source
  124. Resonate: Non-deterministic calls go in a leaf function run via ctx.run. source
  125. DBOS: A workflow function must be deterministic. source
  126. Hatchet: Durable-task code must be deterministic; avoid clock and random reads. source
  127. Cadence: Workflow code must use Cadence APIs for time and must be deterministic. source
  128. Dapr Workflow: Workflow code must be deterministic. source
  129. Lambda durable: Every non-deterministic call must be wrapped in a step. source
  130. Azure Durable: Orchestrator code must not use time APIs or random values directly. source
  131. Cloudflare Workflows: Non-deterministic logic must go inside step.do. source
  132. Vercel Workflow: Math.random and Date are fixed automatically; any other effect must be a step. source
  133. LangGraph: Random numbers and clock reads must be kept inside tasks. source
  134. Temporal: Running workflows continue on new code only for replay-compatible changes; otherwise patching is needed. source
  135. Restate: Requests start and end on the same version. source
  136. Golem: An update replays the agent on the new revision, but must be triggered and falls back if replay diverges. source
  137. DBOS: Only workflows whose version matches the current application are recovered. source
  138. Trigger.dev: A run never changes version. source
  139. Conductor: Running executions keep the definition snapshot taken at start. source
  140. Cadence: Continues on new code only for compatible changes; otherwise GetVersion is needed. source
  141. Dapr Workflow: Continues on new code only while it stays deterministic; otherwise patching. source
  142. Step Functions: A redriven execution uses the same definition; an update needs a new execution. source
  143. Lambda durable: Unpinned executions continue only if steps are not changed in ways that break replay. source
  144. Azure Durable: Running orchestrations replay on new code; breaking changes need version branching. source
  145. Vercel Workflow: Runs are pinned to the deployment that starts them. source
  146. Airflow: Only with the unversioned local bundle do remaining tasks use the latest code. source
  147. LangGraph: Old threads resume on the new graph, but renames break them and changes need a version stamp. source
  148. Restate: Forcing an existing registration is for local development; production versions are new deployments. source
  149. DBOS: Only workflows of the current version are recovered. source
  150. Trigger.dev: A run never changes version, even after new deploys. source
  151. Conductor: Running executions keep their start-time snapshot. source
  152. Step Functions: An updated definition needs a new execution. source
  153. Lambda durable: Unpinned executions may resume on changed code, but the docs recommend pinning. source
  154. Vercel Workflow: Workflows keep running on the deployment they were created on. source
  155. Inngest: A resumed run uses the current code. source
  156. Cadence: Running workflows replay on the updated code. source
  157. Dapr Workflow: Code updates apply to running instances. source
  158. Lambda durable: Executions are pinned when you invoke a version or alias. source
  159. Azure Durable: Version settings can match work to versions; by default code changes affect running work. source
  160. Airflow: With a versioned bundle a run keeps its code; the default local bundle does not. source
  161. LangGraph: The latest graph applies to every thread. source
  162. Resonate: Its blog describes un-sequenced promises rather than a sequenced log. source
  163. LangGraph: Checkpoints accumulate per thread, but are snapshots, not described as a log. source

The full comparisons, with every source →

Demos

The first one starts from an empty project; the others open on finished code and go straight to the run, the crash and the replay.

video coming
Python

One Python loop, four inference engines

An assistant writes a Python orchestrator live. For every photo, in parallel: our CUDA kernels sharpen it, Triton classifies it, llama.cpp describes it; then vLLM writes the album summary.

video coming
Java

Trip booker: crash, rewind, replay

Flight, hotel and car held in parallel, then payment. Kill the server mid-run: it finishes anyway. Rewind the recorded run, fix a bug, replay it against the fix, with nothing booked twice.

video coming
Java

Refund agent with a person in the loop

An agent looks up the order and the policy, drafts a refund, and waits for a person to approve or correct it on a review page. Stop the machine while it waits; nothing is lost.

video coming
Java

FIX: a day of trades, in parallel

Thousands of FIX execution reports, each with a costly cost-of-trading analysis, run as one parallel loop. Kill it halfway: only the unfinished messages run again.

The IDE

A browser IDE for orchestrations. It checks your code as you type, draws the graph the compiler derived, deploys with one gesture, and shows every run step by step.

Checked as you type

The Java language server for completion and errors, and Jaal's own compiler underneath: an unsafe line is refused by name, with the fix.

Your empty space

Sign in with your email. Everything you make lives under your own package, like com.gmail.you.

Publish, deploy, send

Turn a project into an endpoint, deploy it to a node, send it work, watch the run.

Open the IDE by invitation for now

Features

What is built, what is in progress. We say which.

built

A compiler, not an SDK

Plain code in. The compiler derives the workflow graph, decides what is recorded, and refuses what is unsafe, by name.

built

Parallelism by proof

Calls that do not depend on each other run together because the compiler proved it. One measured run went from about 610 ms to 311 ms with no code change.

built

Durable by default

Every step is a transaction in Postgres. A killed process is finished by another from the last recorded step, without re-running the code from the start, and a settled call never runs again.

built

No determinism rules

You do not have to write deterministic code. The compiler works out what is deterministic; a call it cannot see into is recorded, so a random number or a clock read is replayed exactly as it was.

built

Rewind and replay

Step through a recorded run, back and forth. A replayed step is answered from the record: a model or a service is never called twice.

planned

Backtest

Run a changed version against the cases already recorded, with no live system behind them, and see what would have changed.

built

The effect contract

Compensation is declared, not coded: the service states how it is undone and retried, the caller states what a failure means.

built

Versions that hold

A version is its content. Running work stays on its version; new work takes the new one.

built

Python orchestrators

Write the orchestrator in Python; it is checked as you type and compiled to the same graph.

in progress

One IR, three runtimes

The same orchestrator printed as Java, C++ or Rust. The C++ print already runs bit for bit with the Java one.

in progress

Inference orchestration

vLLM, Triton, llama.cpp and plain CUDA as services of one orchestrator, each in its own process.

How this compares with Temporal, Restate, Inngest, Ray, LangGraph and the rest →