TL;DR
If you want the fastest path from existing app code to durable workflows, choose Inngest. If you want the most JavaScript-native job platform with a strong developer experience and a credible self-hosting path, choose Trigger.dev. If your workflow correctness matters enough that you want durable execution baked into service boundaries and not just background jobs, choose Restate.
Quick Comparison
| Platform | npm package | Weekly downloads | Latest | Best for | Biggest tradeoff |
|---|---|---|---|---|---|
| Inngest | inngest | ~802K/week | 4.2.4 | Event-driven functions added to an existing Next.js, Node.js, or serverless app with minimal setup. | It is cloud-first and feels best when you accept its event and step model. |
| Trigger.dev | @trigger.dev/sdk | ~422K/week | 4.4.4 | JavaScript-first durable jobs, cron, waits, and task orchestration with strong DX. | The product people still call “v3” has moved forward; the current SDK is newer, so docs and mental models can drift. |
| Restate | @restatedev/restate-sdk | ~86K/week | 1.13.0 | Durable execution as application infrastructure, especially when correctness and service boundaries matter. | It is the most architectural commitment of the three, not the quickest drop-in job tool. |
Why this matters in 2026
Traditional queue advice is no longer enough. A lot of modern backend work is not just “run this later.” It is:
- wait for an external event without losing state
- retry only the failed step, not the whole job
- coordinate AI calls, webhooks, approvals, and database updates
- survive deploys and worker restarts without writing custom compensation code
That is the problem Inngest, Trigger.dev, and Restate are all trying to solve. They overlap, but they do not sit at the same layer.
What actually changes the decision
- Choose based on adoption friction. Inngest is easiest to add to an app that already exists.
- Choose based on platform ownership. Trigger.dev gives JavaScript teams a very natural task platform, while Restate asks you to adopt a more durable-systems architecture.
- Choose based on what “durable” means in your world. For some teams it means retriable steps. For others it means persisted service calls and workflow state as core infrastructure.
- Ignore client bundle size. These are server-side tools. Operational model beats bundle metrics here.
Package-by-package breakdown
Inngest
Package: inngest | Weekly downloads: ~802K | Latest: 4.2.4 | Bundlephobia gzip: ~51 KB
Inngest wins on time-to-value. It feels like the least disruptive path from “I have a web app” to “I have durable workflows with retries and waits.”
import { Inngest } from "inngest";
export const inngest = new Inngest({ id: "pkgpulse-app" });
export const sendDigest = inngest.createFunction(
{ id: "send-digest" },
{ event: "digest/requested" },
async ({ event, step }) => {
const user = await step.run("load-user", () => db.user.findUnique({ where: { id: event.data.userId } }));
await step.run("send-email", () => emailDigest(user));
}
);
Why teams pick it:
- It slots into existing serverless and Next.js apps with very little ceremony.
- The
step.run()model is easy for most application developers to understand. - Event-driven flows, scheduled work, and waits all feel like extensions of normal app code.
Watch-outs:
- If you want deeper runtime control or a self-hosted-first posture, Trigger.dev is often a better fit.
- If you need durability to be a cross-service architectural property, Restate is stronger.
Trigger.dev
Package: @trigger.dev/sdk | Weekly downloads: ~422K | Latest: 4.4.4 | Bundlephobia gzip: ~75 KB
People still say “Trigger.dev v3” because the big rewrite is what changed the category for many Node.js teams. The important practical point in 2026 is that the current SDK continues that model: long-running tasks, waits, schedules, and a very good JavaScript-native authoring experience.
import { task, wait } from "@trigger.dev/sdk/v3";
export const generateReport = task({
id: "generate-report",
run: async (payload: { reportId: string }) => {
const data = await fetchInputs(payload.reportId);
await wait.for({ seconds: 30 });
return finalizeReport(data);
},
});
Why teams pick it:
- The authoring model feels close to normal async JavaScript instead of workflow DSLs.
- It covers common production needs well: schedules, waits, retries, and background execution.
- Self-hosting is not an afterthought, which matters for teams that do not want all job infrastructure outsourced.
Watch-outs:
- The version story can be confusing because the “v3” label stuck in the ecosystem conversation while the SDK kept evolving.
- If you want the simplest possible adoption inside an existing Next.js codebase, Inngest usually gets there faster.
Restate
Package: @restatedev/restate-sdk | Weekly downloads: ~86K | Latest: 1.13.0 | Bundlephobia gzip: ~620 KB
Restate is the most infrastructure-flavored option in this comparison. It is not just background jobs with retries. It is a durable execution layer for services and workflows.
import * as restate from "@restatedev/restate-sdk";
export const billingWorkflow = restate.workflow({
name: "billingWorkflow",
handlers: {
run: async (ctx, input: { customerId: string }) => {
const invoice = await ctx.serviceClient(invoiceService).create(input);
await ctx.sleep("15m");
return ctx.serviceClient(notificationService).send({ invoiceId: invoice.id });
},
},
});
Why teams pick it:
- Durable state and replay are part of the programming model, not bolted on around individual task steps.
- It is a better match for business-critical workflows that cross service boundaries.
- Teams that care about correctness, idempotency, and recovery semantics tend to appreciate its model more over time.
Watch-outs:
- It is the heaviest conceptual lift here.
- If your actual need is “reliable background jobs for my app,” Restate can be more system than you need.
Which one should you choose?
- Choose Inngest when you want the fastest path to durable functions inside an app you already have.
- Choose Trigger.dev when your team wants a JavaScript-first job platform with better runtime ownership and a strong self-hosting story.
- Choose Restate when workflow durability is part of your core system design and not just a background-task convenience.
Final recommendation
For most application teams, Inngest is the best default because it minimizes migration cost and gets durable steps into production quickly. Trigger.dev is the best choice when your team wants that same category of capability but with a more platform-like feel and more control over where it runs. Restate is the right answer for teams building durable systems, not just durable jobs.
Data note: npm package versions and weekly download figures were checked against the npm registry on 2026-04-24. Bundle figures come from Bundlephobia.
Related reading
Hatchet vs Trigger.dev v3 vs Inngest · Temporal vs Restate vs Windmill · Best Node.js Background Job Libraries 2026