Every offer link is checked before it’s shownOffer links may earn us a commission. How we make money
Find my match
Developer SoftwareMade4Buyers

Temporal vs Inngest vs Trigger.dev vs BullMQ 2026

A comparison of Temporal, Inngest, Trigger.dev and BullMQ for background jobs: Inngest is the default pick for serverless TypeScript, Temporal for mission-critical workflows.

Team of developers working together on computers in a modern tech office.
Representative photo · Photo by cottonbro studio on Pexels

Review

Sooner or later, most backends need work that cannot finish inside a single request: processing a forty-minute video upload, provisioning an account the instant a Stripe webhook lands and then nudging it about its trial two weeks later, or replacing the setTimeout that someone tucked into a serverless function before discovering execution limits the hard way. Four tools dominate that conversation in 2026, and each wins a different scenario.

The short version: Inngest is the strongest default for TypeScript teams deploying to serverless platforms; Temporal belongs where a workflow dying midway would cost real money; Trigger.dev is best for lengthy, compute-hungry jobs such as media processing and AI pipelines; and BullMQ is still correct for teams that already run Redis and whose jobs consist of a single step.

Queues versus durable execution

The marketing pages blur together, but the documentation reveals two distinct categories. A job queue, which is what BullMQ is, saves a message, dispatches it to a worker, and reruns the entire job when the worker throws. That is quick and simple, yet it falls apart once a job performs several side effects in sequence: a failure after the third step means the first two execute again. Teams in that position typically build a home-grown checkpoint table in Postgres whose status column keeps sprouting new states, eventually eleven of them.

Durable execution platforms instead record the outcome of each step. A retry skips completed steps and resumes at the point of failure with local variables preserved, and a workflow may stay dormant for a month with no process held open. This model is offered by Temporal, Inngest and Trigger.dev alike, yet their implementations diverge so sharply that architecture outweighs any feature checklist.

Temporal

Temporal grew out of Uber's Cadence project, carries an MIT license and is the heavyweight of the group. Workflows are ordinary programs written in Go, Python, TypeScript, Java, Ruby, PHP or .NET. Self-managed workers pull from task queues hosted by the Temporal server, which logs every event in each workflow's history. If a worker crashes, another one replays that history and reconstructs the state at the precise point of failure. No other option here has been proven in production as thoroughly; it powers order and payment pipelines in organizations where any stuck workflow lands in an incident review.

Replay imposes constraints. Workflow code has to be deterministic, so clock reads and network calls are banned inside workflows and must move into activities. Modifying a workflow while older runs remain in flight demands versioning via patching APIs in the SDK; mistakes surface as nondeterminism errors on executions started days earlier. Each execution's history is capped at 50,000 events or 50 MB, so long loops need Continue-As-New to begin a new history. Newcomers realistically need a full week to become productive, and teams should plan for it.

Self-hosting involves the Temporal server plus a persistence layer, usually Postgres or MySQL, or Cassandra for very large deployments, plus an Elasticsearch-compatible store for advanced search across executions. Many teams self-host successfully, but more migrate to Temporal Cloud, which charges per action plus storage and takes the least pleasant on-call duties off their plate.

Inngest

Inngest flips the model: there are no workers to operate. Functions are exposed via an HTTP handler mounted in the existing application, such as an Express endpoint or Next.js route, and Inngest calls it whenever an event comes in. Every step.run() call is its own invocation with a memoized return value; if step four fails, the retry is handed the saved results of steps one to three without rerunning them. step.sleep() and step.waitForEvent() can pause a function for days without consuming compute.

Teams deploying on Vercel or Netlify will find it nearly effortless. Nothing new needs to be hosted, and individual steps stay well within serverless timeouts because no single step carries the whole load. Flow control is its understated advantage: throttling, debouncing, rate limiting, priority and per-key concurrency limits each take one line of configuration, which keeps one large customer's bulk import from crowding out everyone else. Its local dev server lays out each run and its individual steps in a browser UI, the best debugging setup among the four.

The design has costs. Because every step costs an HTTP round trip, splitting a function into two hundred small steps makes it slower and pricier than on Temporal, so work should be grouped inside steps. Since billing is based on executions and steps, coarse-grained steps are rewarded. SDKs exist for TypeScript, Python and Go, with TypeScript receiving features first. A self-hosted server is available and suits smaller deployments, though most teams use the cloud service, and security reviewers should note that event payloads travel through Inngest.

Trigger.dev

Trigger.dev once resembled Inngest but took a different path with version 3. Tasks are TypeScript files kept in the repository, deployed with Trigger.dev's CLI, and run on Trigger.dev's managed compute rather than inside the application. That eliminates timeouts altogether: an hour-long video transcode, or a sequence of eight LLM calls each retried independently, simply runs to completion. Machine size is chosen per task, useful when a single job requires 8 GB of memory while the rest need very little.

Waiting relies on checkpointing. Calling wait.for(), or pausing for a child task, causes the runtime to snapshot the process and resume it afterwards, with no charge for the idle period. The Realtime API streams run status and metadata into a React frontend; that has quietly become a standout for AI apps that show a progress bar while a generation runs for three minutes. Build extensions take care of awkward dependencies such as Puppeteer, FFmpeg, Prisma and bundled Python scripts, with no custom Dockerfile needed.

It supports TypeScript only. Pricing charges for compute time plus a small fee on each run, so tasks that mostly wait on external APIs are cheap, while an hour of heavy CPU costs roughly an hour of CPU. Licensed under Apache 2.0, it can be self-hosted with Docker or Kubernetes, giving it an edge over Inngest for teams with strict data-residency requirements. Its flow control is less extensive than Inngest's, although queues with concurrency limits handle most real-world needs.

BullMQ

BullMQ is an MIT-licensed Node.js library on top of Redis, with no vendor involved and nothing extra for security to sign off on. Mature features include retries with exponential backoff, delayed jobs, priorities, rate limiting, parent-child flows and cron-style schedulers, and the Redis instance is the main ceiling on throughput. For tasks like sending email or running a nightly CRM sync, it has worked reliably with minimal setup for years.

What it lacks is durable execution. Multi-step state must be modeled by hand, and observability depends on add-ons, typically the free Bull Board or the paid Taskforce.sh. Redis must be configured for persistence and set to the noeviction memory policy; that setting is overlooked so often it has become a cautionary tale, because a Redis instance that evicts keys drops jobs without warning.

Other options

Hatchet, a Postgres-based durable task queue under the MIT license, is a sensible choice for Inngest-style steps without Redis or an external vendor. Restate takes a lighter-weight approach and merits a look if Temporal's determinism rules intimidate a team. AWS Step Functions works for organizations fully on AWS that are comfortable with JSON state machines. At smaller scale, pg-boss provides a capable queue inside an existing Postgres database.

Whatever the choice, every one of these systems will occasionally execute a side effect twice on a bad night, so idempotency keys should always be passed to Stripe.

Recommendation

Teams deploying TypeScript to a serverless platform should start with Inngest, which delivers fan-out, retries, sleeps and strong flow control without any new processes and can reach production within an afternoon. Trigger.dev is the better choice when a single job lasts minutes or hours, or when progress needs to stream to the UI, with AI features the obvious example. Temporal is the pick when workflows involve money or must withstand every conceivable failure, and its learning curve is the price of that assurance. BullMQ remains fine for teams with Redis already in place and genuinely single-step jobs, which describes most jobs until one picks up an extra step and the retry charges a customer twice.

Temporal leads the scoring at 8.8/10, ahead of Inngest (8.6/10), Trigger.dev (8.4/10) and BullMQ (7.9/10), while the verdict names Inngest the best default and Temporal the choice for mission-critical workflows.

Products compared (4)

Each product links to everything we have filed about it. We don’t pick a winner the source didn’t.

Key facts

Key facts about Temporal vs Inngest vs Trigger.dev vs BullMQ
ComparesTemporal vs Inngest vs Trigger.dev vs BullMQ
CategoryDeveloper Software
TypeCloud & hosting
Best forComparison, Productivity

Buying considerations

How we filed this product. Each link shows other reviewed developer software that share it.

Good fit for

Alternatives to consider