Workflow Engines: When You Need Temporal, When You Need Cron
A workflow engine runs multi step processes that have state, branching logic, and the need to survive failures and restarts. Cron schedules recurring single tasks. A job queue runs discrete background work. The three tools overlap in marketing but not in design. Choosing a workflow engine for a cron job is over-engineering. Choosing a cron job for a multi-step business process is a reliability disaster.
Written by Yashveer Singh, founder of Yashveer Labs.
What you actually need to know
- Cron is for simple recurring tasks with no cross-run state.
- A job queue is for discrete background work that runs once per trigger.
- A workflow engine is for multi-step processes with state, branching, and durable execution.
- The three tools are not interchangeable. Using the wrong one makes the right problem much harder.
- Most early stage SaaS products need cron and a job queue. A workflow engine is earned, not assumed.
| Tool | Best fit | State management | Step level retries | Observability |
|---|---|---|---|---|
| Cron (native, Cloud Scheduler) | Scheduled single tasks | None | No | Minimal |
| Job queue (Postgres, BullMQ) | Discrete triggered work | None | At job level | Good |
| Inngest | Multi-step managed workflows | Durable | Yes, per step | Built in dashboard |
| Trigger.dev | Multi-step managed workflows | Durable | Yes, per step | Built in dashboard |
| Temporal Cloud | Complex durable workflows | Durable | Yes, per step | Web UI, full history |
| AWS Step Functions | AWS-native workflows | Durable | Yes, per step | CloudWatch |
The core argument
Cron, a job queue, and a workflow engine are presented in similar marketing language. "Run background work." "Schedule tasks." "Handle async processes." The vocabulary overlaps enough that many teams pick the first option that sounds right and spend months paying for that choice.
The distinction is simpler than the marketing suggests. Cron schedules recurring work. A queue runs work triggered by events. A workflow engine runs work that has steps, state, and the need to survive failures without starting over. Each tool does one thing well. None of them does all three.
The team that runs a subscription renewal check on a cron job is making the right choice. The team that runs a user onboarding flow on a cron job with a dozen database flags tracking which step each user is on has invented a broken workflow engine. I have inherited several of those. They break in different ways at every scale. The state tracking is always incomplete. The failure handling is always wrong. The observability is usually zero.
The team that reaches for Temporal on day one for sending welcome emails has the opposite problem. Temporal is a serious piece of infrastructure. It is the right tool for the right problem. Sending a single email is not that problem.
The practical question is where to draw the line. The answer I use: if the process has three or more sequential steps with different failure modes, if any step can wait on an external event, or if you need to know the state of an in-flight process at any given moment, reach for a workflow engine. Otherwise, a queue is sufficient.
The three tools, concretely
Cron
Cron is correct for: nightly report generation, subscription trial expiry checks, cache cleanup, scheduled data sync from a third party, anything that runs on a schedule and starts fresh each time.
The failure model is simple. If the job fails, it either retries or it does not, depending on the scheduler. The next run starts fresh. There is no state to recover. Managed cron options like Cloud Scheduler, Render Cron Jobs, and in-queue schedulers all work well. The operational overhead is minimal.
Job queue
A queue is correct for: welcome email on sign up, file processing after upload, webhook delivery, report generation triggered by user action, third party API calls, anything that runs once in response to an event.
The failure model is retry with exponential backoff and dead letter handling. Each job is independent. A failed job does not affect other jobs. The queue has no concept of steps or state between jobs. If you find yourself using a queue job to set a database flag that the next queue job checks, you are building a poor version of a workflow engine.
Workflow engine
A workflow engine is correct for: user onboarding that spans multiple days, payment reconciliation across multiple systems, provisioning flows that call multiple APIs in sequence, document processing pipelines with human review steps, anything that has steps and needs to know where it is.
The engine persists the workflow state after each step. A worker crash does not lose the workflow. The workflow resumes from the last successful step. Each step has its own retry policy. The engine can pause the workflow until an external event arrives, such as a user clicking a confirmation link or a payment completing.
What it costs
| Option | Setup time | Monthly cost at moderate scale | Operational overhead |
|---|---|---|---|
| Native cron (in existing scheduler) | Hours | Negligible | Minimal |
| Cloud Scheduler (GCP) | Half a day | Under 5 USD | Minimal |
| Job queue (already have Postgres) | Half a day | Negligible | Negligible |
| Inngest | One day | Free to 250 USD | Minimal, managed |
| Trigger.dev | One day | Free to 250 USD | Minimal, managed |
| Temporal Cloud | Two to three days | 25 USD per million actions | Medium |
| Self-hosted Temporal | One to two weeks | Infrastructure cost | High |
Features to look for
- Durable state persistence. Workflow state survives worker restarts.
- Per-step retry policies with configurable backoff.
- Workflow visibility. You can see every in-flight workflow, its current step, and its history.
- Event-driven step triggers. A workflow can pause and wait for an external signal.
- Cancellation and termination. You can stop a workflow in progress.
- Versioning. You can deploy new workflow code without breaking in-flight workflows.
- Local development support. You can run the workflow engine in development without a production dependency.
Expert opinion
I have watched teams reach for Temporal when they needed a queue, and reach for cron when they needed a workflow engine. The first group spent their initial sprint learning an infrastructure tool instead of shipping product. The second group spent the next year maintaining a state machine built out of database flags and job logic. Both mistakes are expensive. The workflow engine conversation should start when the team has a concrete problem that cron and queues cannot solve cleanly. Before that point, it is a solution looking for a problem.
>
Yashveer Singh, founder of Yashveer Labs
How this played out on a real project
A SaaS client had a user onboarding flow that took three to five business days to complete. It involved provisioning a resource, waiting for a third party API to confirm provisioning, sending a series of guided setup emails at specific intervals, and notifying the sales team at the end. The flow was implemented as four cron jobs, each checking a status column on the user record.
The status column had twelve possible values by the time I saw the codebase. Five of them were dead states that users could reach but never escape from without manual intervention. The sales team had a spreadsheet for tracking users stuck in dead states. There were consistently thirty to fifty of them at any given time.
We migrated the flow to Inngest over two weeks. The workflow is readable code with named steps. Each step has its own retry policy. The Inngest dashboard shows every in-flight onboarding, its current step, and any failures. The dead states are gone because the workflow handles the failure cases explicitly. The sales team spreadsheet is gone.
The migration was two weeks of work that eliminated a class of recurring support burden. The codebase is smaller. The behavior is more predictable. For related infrastructure, background job queues the architecture decision founders skip covers the queue layer this sits on top of, and why your saas should have a job queue from day one covers the simpler adjacent tool.
Common mistakes
- Using a cron job with database flags to simulate a workflow. It breaks in every direction and is impossible to debug.
- Reaching for Temporal before having a concrete multi-step process problem. The operational overhead is real.
- No visibility into in-flight workflows. When something goes wrong, you have no way to inspect the state.
- Workflow code that cannot handle retries. The engine will retry steps. The code has to be safe to run more than once.
- No versioning strategy. Deploying new workflow code while old workflows are in flight causes state mismatches.
- Using a workflow engine for simple scheduled tasks. Cron is correct for that. The engine adds cost and complexity with no benefit.
- One retry policy for all steps. A step that calls a third party API needs different backoff than a step that writes to your database.
A four week plan
- Week one. Audit existing cron jobs and background work. Identify any that have grown into multi-step processes. Map the steps explicitly.
- Week two. For the identified multi-step processes, pick a workflow engine. For teams on Next.js or serverless, Inngest or Trigger.dev. For teams with more complex needs, evaluate Temporal Cloud.
- Week three. Migrate one multi-step process to the workflow engine. Run the old and new implementations in parallel. Compare outputs.
- Week four. Cut over. Migrate remaining candidates. Document which work belongs in cron, which belongs in the queue, and which belongs in the workflow engine. New processes follow the map.
For deeper reading on the job layer below workflows, background jobs at scale Inngest Trigger Cron and beyond covers the managed options in detail.
Frequently asked
The engineering bet behind Yashveer Labs
The bet I am running with Yashveer Labs is simple. Most software is built by people who treat it as a job. I treat it as a craft. Yashveer Singh, founder. Five production systems on the board so far. The arc points at machine learning, AI engineering, and cybersecurity. If your project is in any of those orbits, you are reading the right page.
Posts that line up with this one.
- SaaS Architecture and Scaling
Idempotency in API Design: Why It Matters More Than You Think
An idempotent API is one that handles repeated requests gracefully. Building it in from the start is far cheaper than retrofitting it after your first double-charge incident.
- SaaS Architecture and Scaling
Internal Admin Tools: Build vs Buy vs Retool
Every SaaS needs internal tools. The question is whether to build them, buy a platform like Retool, or use a lighter alternative. Here is the decision framework that saves engineering hours without creating tool debt.
- SaaS Architecture and Scaling
Job Failure Recovery: How Good SaaS Companies Sleep at Night
Every background job will fail eventually. The companies that sleep at night are the ones that built failure recovery into the system from day one, not as an afterthought when something broke in production.
- SaaS Architecture and Scaling
Monolith vs Microservices: Why Most Startups Get It Wrong
Microservices are the architecture that works at Netflix and fails at early-stage startups. Here is why the monolith is the right default, when microservices become rational, and how to make the transition without breaking everything.