A workflow is code. Every step lands in its history.
One open run per workflow ID, such as order-42. Activities do the side effects; timers and signals wait durably.
Status column and cron job?
Bad: Status column + sweeper
Crash after PAID: the order sticks. Two sweepers grab one row.
Good: One durable function
Every step, timer and message is recorded. A crash resumes on another worker.
Worker A dies. Worker B replays from the first line.
Finished steps return results from history, with no new calls. Only the first unseen step runs. So workflow code must be deterministic.
Worker 1 charges ₹1,499, then dies before reporting it.
The catch
Activities run at least once: after Start-To-Close, Worker 2 retries. Only the gateway’s idempotency key, order-42:charge, stops a second charge.
51,200
events or 50 MB terminate a run
A loop adds about 6 events per activity: warned near 1,700 iterations, terminated near 8,500. Continue-as-new: same ID, fresh history.
Workers poll. History shards are fixed for life.
Frontend routes each workflow ID to one History shard. Every state transition is a database write: the database is the ceiling.
Pick it, or not
- Pick: multi-service processes waiting on time or people
- Not: one step, or fire-and-forget
- Not: high-volume streams such as clicks, GPS pings
- Not: latency-critical paths, or no one to run it
Say it like this
I’d pick Temporal for long, multi-service processes: ID order-<id>, retried activities, durable timers, compensations in reverse. Activities run at least once, so key the charge. Not for streams or one-step jobs.