LangGraph or Temporal? Durable execution from two directions
The client already ran Temporal. Their payouts, their retries, their ledger writes, all of it lived in Temporal workflows that had moved real money for the better part of two years without losing a cent. So when we bolted an LLM step onto their invoice pipeline, the obvious move was to write the agent as more Temporal activities. I didn't. That call, and the small disaster that led to it, is what this piece is about.
two roads to the same promise
Both tools promise the same thing: a workflow that survives a crash and resumes where it stopped. They arrive from opposite directions. Temporal comes from the workflow-engine world: you write ordinary code, it records an event history, and it replays that history deterministically to rebuild state after a failure. It runs any logic, it's been hardened by years of people pushing money through it, and it asks for real operational commitment: a server cluster or the hosted product, worker fleets, versioning discipline. LangGraph comes from the agent world. State is a typed dict, durability is a row in Postgres via a checkpointer, and the whole thing assumes a language model sits somewhere in the loop, so interrupts for human review, token streaming, and message reducers arrive for free. Lighter to run. Younger, and it shows at the edges.
where I drew the line
The invoice flow reads a PDF, asks a model to classify and extract, decides pay-hold-reject, and on a pay it credits the customer. I put the first three on LangGraph and left the fourth exactly where it already lived, in Temporal. The graph owns the model reasoning, the resume-after-crash of a half-finished analysis, and the human interrupt when a decision needs a person. Temporal owns anything that touches the ledger. The two talk across a queue: the graph emits a decision, a Temporal workflow consumes it and does the irreversible part. async-agent-architecture is the general shape of that seam.
the double-post that set the boundary
I didn't start there. My first prototype was tidy and wrong: one graph, money movement included as a node, because keeping it in one place felt clean. Then during a crash-recovery test a thread resumed from its last checkpoint and re-ran the node that posted a ledger entry. LangGraph resumes by re-executing from the checkpoint, my node had a side effect, and staging cheerfully double-posted a credit. I caught it in staging, not prod, which is the only reason I can write about it this lightly. It drew the line permanently.
A checkpoint is not a transaction; it will happily run your side effect twice and feel fine about it.
Temporal has spent years on precisely this problem: idempotency keys, deterministic replay, activity-level guarantees. LangGraph's checkpointer is durable in the sense that your state comes back, not in the sense that the outside world got touched once. Replaying a reasoning node is free. Replaying a payout is a phone call from the client. Know which kind of node you're writing before you write it.
the advice I would give the reader I was
Here's the part that generalizes past my client. Don't make your first agent system and your first durable-execution system the same project. Mine got away with the split because they already knew Temporal cold; the only new thing was the agent, and I let LangGraph's built-in durability carry it. If both are new to you, one of them will teach you its failure modes at the worst possible moment. Put the boring, known thing on the irreversible work, and let the graph be new only where mistakes are cheap. That's the same instinct as build-vs-buy-thin-harness: adopt one unfamiliar system at a time, and never the one holding the money.
If your workflow is mostly model calls with a human in the middle, LangGraph feels native and Temporal feels like paperwork. If it's mostly irreversible side effects with a little AI sprinkled on top, invert that. Most real systems are both, which is why mine became two systems with a queue between them, and why I stopped trying to make one tool do the whole job.