Compare

Dex and other durable execution engines.

Durable execution engines all keep a process running through failures. They differ in how you change running code, what you can see, where business data lives and what you have to operate.

Replay-based enginesDex
Changing code of running processesRecovery replays workflow code against its history, so a change that alters the sequence of steps needs a version branch in the code.Each Step's result is recorded. Running Flows continue on new code from their next Step.
Code rulesWorkflow code must be deterministic: no direct I/O, clocks or random numbers outside special APIs.A Step's code is ordinary code. Waiting is declared, not written as blocking calls.
Seeing a runA list or timeline of history events.A graph generated from the code, with each run drawn on it: where it is, what it waits for, what happened.
Business dataKept in workflow variables or in your own database; searching across runs needs extra setup.Attributes: durable, indexable and searchable across runs, with optional writes to PostgreSQL, MySQL, Snowflake, Databricks or MongoDB.
Calling other systemsYou write the client code.More than 60 open-source connectors, such as Slack, Gmail, Salesforce and Stripe.
Running the serverA server cluster with a database, often with a search cluster beside it.Managed for you today. In development: a single binary that stores everything in object storage such as S3.

Replay-based engines are mature and widely used, with large ecosystems. The rows above describe their common design, not every product.

Why changing code matters now.

A process that improves from its own runs changes every week. Thousands of its runs are waiting at any time, some for days. With replay, each change has to keep every old path in the code until those runs finish. With Dex, you change the Step and deploy.

lead_follow_up.pyDex Python SDK
class WaitForReply(Step[Lead]):
    def wait_for(self, ctx, lead):
        return Wait.any_of(
            lead_replied.for_one(),
            # Changed this week: follow up after 2 days, not 5.
            Timer.by_duration(timedelta(days=2)),
        )

Try the programming model.

The quick start runs a Flow on your machine in a few minutes.