Trigger.dev vs Inngest
Durable AI agents and workflows need somewhere to run. Inngest orchestrates functions in your existing app step by step. Trigger.dev runs your code on its own managed compute. Choose Inngest if you work in Python or Go, your system is built around events fanning out to many functions, you want your agent code to ship in the same app and deploy, or you want built-in scoring and experiments. Choose Trigger.dev if you want a TypeScript-first platform built for AI agents: durable chat agents with chat.agent, versioned prompts you can change without a redeploy, evals you write as ordinary tasks, custom dashboards over your runs and AI SDK calls, and agents that run as long as they need on managed compute, with no step or request timeout.
What is Trigger.dev?
Trigger.dev is the open source platform for building durable AI agents and workflows in TypeScript. Your code runs on managed compute as normal TypeScript, with no determinism constraints and no platform-imposed execution timeout. It includes built-in retries, queues, and scheduling, plus OpenTelemetry observability with custom dashboards and an SQL-style query language. Tasks can stream data to your frontend and backend in real-time, receive typed input while running, and pause for hours, days, or weeks for human approval or external events. Thousands of engineering teams run production workloads on it, processing hundreds of millions of runs.
What is Inngest?
Inngest is a durable execution platform that orchestrates functions in your own app via HTTP callbacks or persistent outbound connections (connect()). It's often used with serverless platforms like Vercel, but it also works on regular servers and containers. It supports TypeScript, Python, and Go with adapters for 20+ frameworks including Next.js, Express, Remix, and Hono. Inngest's step-based memoization ensures that completed work is never repeated on retry. The event-driven model with step.waitForEvent(), built-in concurrency controls, rate limiting, and debouncing make it well-suited for event-driven architectures. AgentKit adds AI agent orchestration with MCP tool support and React hooks for streaming agent output.
Feature deep-dive
How does the execution model differ?
Inngest orchestrates your code on your own infrastructure, subject to your host's limits. Trigger.dev runs your code on managed compute with no platform-imposed timeout.
| Feature | Trigger.dev | Inngest |
|---|---|---|
| Where your code runs | Managed compute on Trigger.dev Cloud, or your own infrastructure if you self-host | Your own app |
| Uninterrupted execution limit (per task / per step) | No platform limit. You set your own maxDuration (it counts compute time, not waits), or turn it off with timeout.None | Per step: your host's request timeout (Vercel: up to 800s, Lambda: 15 min), capped at 2 hours |
| Step model | No steps required, write regular TypeScript. Subtasks with idempotency keys are the units that don't re-run on retry | Steps are memoized. The TS SDK runs sequential steps in one request by default, and replays on retry or parallel steps |
| Replay behavior | None (checkpoint-resume snapshots) | Memoized replay (checkpointing enabled by default, executes sequential steps eagerly) |
| Non-deterministic code | Write anything, anywhere | Place inside step.run() to avoid re-execution on replay |
| System dependencies | Build extensions (Prisma, FFmpeg, Playwright, Puppeteer, Python, apt packages, and more) or write your own | Whatever your host provides (on your own servers or containers you can install anything) |
| Total workflow duration | No platform limit. Waits don't count toward maxDuration | Many steps and waits per run, up to the plan's max run length (30 days on Free, 90 on Pro, 366 on Business) |
| Running steps longer than your host's timeout | Not needed. Tasks have no platform timeout | Inngest calls your app over HTTP to run steps, so each step runs within your host's request timeout. On an always-on server, you can use connect() instead, and each step can run for up to 2 hours |
Inngest's callback model means your functions stay on your infrastructure, and Inngest handles orchestration, retries, and scheduling via HTTP. This works well when each step completes within your platform's timeout. For longer tasks, Inngest's connect() mode provides a WebSocket alternative for long-running servers. Durable Endpoints (in beta) add step-based checkpointing to regular HTTP handlers in Next.js and Bun. Trigger.dev runs your code on its own compute instead, so a task that takes 30 seconds or 30 minutes runs the same way, without depending on your host's request timeout (you set a maxDuration per task, or turn it off).
How does developer experience compare?
Inngest provides a rich step-function API with event triggers, sleep, and fan-out primitives. Trigger.dev has a simpler model: tasks that run as plain TypeScript with built-in queues and scheduling.
| Feature | Trigger.dev | Inngest |
|---|---|---|
| Core concept | Tasks | Functions with steps |
| Trigger types | Direct trigger, batch trigger, scheduled (cron + dynamic schedules) | Events, cron, webhooks |
| Child task invocation | triggerAndWait / batchTriggerAndWait | step.invoke() |
| Waiting for external input | Waitpoints (wait hours, days, or weeks, with an optional timeout) | step.waitForEvent() (requires a timeout) |
| Sleeping | wait.for() / wait.until() (days, months, or longer) | step.sleep() (up to the plan's max run length: 30 days on Free, 90 on Pro, about 1 year on Business) |
| Framework integrations | Any Node.js/TypeScript project | 20+ adapters (Next.js, Express, Remix, Hono, etc.) |
| Local development | Hot reload via CLI (requires internet) | Local Dev Server (runs on your machine, no account or keys) |
| Debounce | Built-in with leading/trailing modes | Built-in debounce per key (1s to 7d period, optional max timeout) |
| Type safety | Full TypeScript types, schemaTask with Zod, ArkType, Valibot, TypeBox, etc. | Full TypeScript types (Standard Schema: Zod, Valibot, ArkType) |
| AI coding tools | MCP server (docs, metrics, trigger, monitor, deploy), skills, llms.txt | MCP servers (dev server and Cloud), agent skills, Claude Code and Codex plugins, llms.txt |
Inngest's DX shines in event-driven architectures. Define a function, specify an event trigger, and Inngest calls your code when the event fires. The step primitives (step.run(), step.sleep(), step.waitForEvent()) are well-designed and intuitive for breaking work into durable units. Inngest supports Standard Schema validation for type-safe event payloads. Trigger.dev's model is different: define a task, trigger it from your code, and it runs on managed compute as plain TypeScript, close to a normal async function. Both platforms ship MCP servers and agent skills for AI editors. Inngest's plugins bundle skills, MCP config, and an eval harness for Claude Code and Codex. Trigger.dev's MCP server connects to the cloud platform for deploying, triggering tasks, and monitoring runs. Its skills (npx trigger.dev@latest skills) are version-pinned to your installed SDK, and a one-line setup prompt takes a coding agent from login to a first local run.
How does durability work in each platform?
Inngest memoizes each completed step and replays to resume. Trigger.dev continues from a snapshot after waits, and on failure retries, reusing subtasks with idempotency keys.
| Feature | Trigger.dev | Inngest |
|---|---|---|
| Durability model | Checkpoint-resume (process snapshots) | Step-based memoization with function replay |
| On failure recovery | Retry from the start, reusing completed subtask results (with idempotency keys) | Replay function, skip memoized steps |
| Continuing after a wait | Restore the process snapshot on the same line | Replay function, skip memoized steps |
| Code constraints | No determinism rules. Retries start from the top, and subtasks with idempotency keys return their saved results | Side effects go inside step.run() |
| Max steps per run | No step concept, so no step limit | 1,000 steps per function |
| Step return data limit | No limit on in-process data. Task payloads up to 3 MB and outputs up to 10 MB, offloaded to object storage automatically | 4 MB per step return |
| Function state size | Grows with process memory | 32 MB total |
Inngest's memoization model: wrap each unit of work in step.run(), and if the function retries, completed steps return their cached result instead of re-executing. Inngest's TypeScript SDK enables checkpointing by default, executing sequential steps eagerly on your server without a round-trip per step, which lowers inter-step latency. Standard replay kicks in on failure or parallel steps. When a run resumes after a wait or a failure, it walks through previously completed steps, so a function with many steps carries more replay overhead at those points. Trigger.dev uses checkpoint-resume instead: the platform snapshots your entire process state at wait points and restores it later. Your code runs forward from the checkpoint rather than replaying from the start, so step count doesn't affect resume cost. When a run fails, Trigger.dev retries it from the start, and subtasks triggered with idempotency keys return their saved results instead of running again.
How do AI agent capabilities compare?
Inngest has AgentKit, a dedicated framework for multi-agent orchestration with MCP tools and React hooks. Trigger.dev runs any TypeScript AI framework with no platform-imposed timeout, real-time streaming, and human-in-the-loop primitives.
| Feature | Trigger.dev | Inngest |
|---|---|---|
| Durable chat agents | chat.agent: one durable machine per conversation, no platform timeout, memory across turns | AgentKit (agents run inside the step + replay model) |
| AI framework approach | Any TS framework (AI SDK, Mastra, OpenAI Agents SDK, etc.) | Any model SDK inside steps (durable agents in TS, Python, or Go), plus the optional AgentKit framework (TS) |
| Tasks as AI tools | ai.toolExecute() exposes tasks to the Vercel AI SDK | AgentKit tool system with MCP support |
| Real-time updates | Run updates (status, metadata) + Streams (AI tokens, progress) to frontend and backend | Realtime channels and topics built into the SDK, with a useRealtime React hook |
| Frontend hooks | useRealtimeRun, useRealtimeStream, useWaitToken, useInputStreamSend, etc. | useRealtime, plus AgentKit's useAgent (docs also describe useChat and useThreads) |
| Human-in-the-loop | Waitpoints pause a task for approval (hours, days, or weeks) | step.waitForEvent() (max timeout) |
| Bidirectional communication | Input streams (typed data into running tasks) | Send events to waiting steps |
| Maximum uninterrupted execution per task/step | No platform limit (you set maxDuration, or turn it off) | Per step: your host's timeout, capped at 2 hours |
| Multi-language agents | TypeScript (Python scripts via build extension) | AgentKit: TypeScript only. General functions: TypeScript, Python, Go |
| Agent environment | Fully customizable machine via build extensions (Python, Playwright + browsers, FFmpeg, system packages), with configurable CPU/RAM per run | Your host's runtime and limits, plus Sandboxes (access-gated beta) for isolated microVM code execution |
Inngest's main approach is durable agents: you write the agent loop with any model SDK, and each LLM or tool call is a step. Inngest's AgentKit adds a structured framework on top: define tools, configure models (OpenAI, Anthropic, Gemini, Grok, and OpenAI-compatible models), and use routing to coordinate multiple agents. AgentKit's React hooks stream agent output to the frontend. AgentKit agents run within Inngest's step-based execution model, so each LLM call is a memoized step with automatic retry. step.ai.infer() proxies LLM requests through Inngest's gateway, reducing serverless compute costs while waiting for responses. Trigger.dev works with any TypeScript AI framework directly: AI SDK, Mastra, OpenAI Agents SDK, or others, with no wrappers. ai.toolExecute() exposes tasks as tools for the Vercel AI SDK. Realtime pushes run updates and streams data (AI tokens, progress) to your frontend or backend, input streams send typed data into running tasks (cancel signals, approvals, user messages), and long-running agent conversations aren't bound by a platform timeout. For chat specifically, chat.agent gives every conversation its own durable machine that you point the AI SDK's useChat at, with run tracing and an AI metrics dashboard (tokens, cost, and latency per model) built in. Because tasks run on managed compute you shape with build extensions, an agent can drive a real browser (Playwright), run Python, or use FFmpeg without bundling any of it into a serverless function.
What infrastructure do you need to manage?
Inngest adds durability to your existing infrastructure. Trigger.dev provides the compute for background work on Trigger.dev Cloud, or you self-host it.
| Feature | Trigger.dev | Inngest |
|---|---|---|
| Compute provider | Trigger.dev Cloud (managed) or self-hosted | Your own hosting (serverless, servers, or containers) |
| Infrastructure to manage | None (cloud) or Docker Compose/K8s (self-hosted) | Your app's deployment + an Inngest endpoint or worker |
| Build customization | Build extensions (Prisma, FFmpeg, Playwright, Python, custom) | Whatever your hosting platform supports |
| Deploy integrations | GitHub auto-deploy, Vercel integration (env var sync, version skew protection), CLI | Syncs on deploy via PUT to your serve endpoint |
| Environments | Production, Staging, Preview (per-branch), Development | Production, branch environments (auto-archive, Vercel/Netlify/Render) |
| Compute isolation | Each run gets its own container (configurable CPU/RAM) | Whatever your host provides |
If you already have an app deployed, Inngest's model is convenient: add the SDK, expose an endpoint, and Inngest orchestrates your existing infrastructure. You keep your current hosting, CI/CD, and deployment pipeline. The tradeoff is that background jobs then run under your web app's limits (on serverless, that means the same timeouts, cold starts, and runtime as your web requests). Trigger.dev provides its own compute, so background tasks are decoupled from your web app entirely. Run FFmpeg, Playwright, or long-running AI agents without worrying about serverless limits. Build extensions add system dependencies with a config line. The Vercel integration syncs environment variables and adds version skew protection, and preview branches create isolated environments per PR with their own runs, schedules, and branch-level env vars.
How does pricing compare at scale?
Inngest bills per execution, counting the run plus each step (a 5-step run is 6 executions). Trigger.dev bills per compute-second plus a per-run fee. The models favor different workload shapes.
| Feature | Trigger.dev | Inngest |
|---|---|---|
| Pricing model | Compute-seconds + per-run fee | Per-step execution + concurrency tiers |
| Free tier | Free plan with monthly usage included | 50,000 executions/mo, 5 concurrent steps |
| Pro tier | See pricing | Pro tier with more executions and concurrency (see pricing ) |
| What counts as a billable unit | Compute time (per second, by machine size) plus a flat fee per task run, however many steps it has | Executions: 1 when the run starts, plus 1 for each step |
| Self-hosted cost | Free (Apache 2.0) + your infra | Free (SSPL) + your infra |
Inngest's per-execution pricing scales with function complexity. Each run counts as the run itself plus every step, so a 5-step run is 6 executions and 100,000 runs of that function is 600,000 executions against your plan. This model works well for simple functions with few steps. Trigger.dev charges for compute time: a task that runs for 10 seconds costs the same whether it has 1 logical step or 50 internal operations. Which is cheaper depends on the workload. On Inngest, add your own hosting bill to the execution count. On Trigger.dev, cost depends on machine size and run time (including retries), plus a per-run fee for every task and subtask, so a workflow that splits work into subtasks, like the order example below, pays several run fees. Many-step work often favors Trigger.dev, while short functions with few steps can cost less on Inngest.
How does observability compare?
Inngest provides traces, Insights SQL queries with an AI assistant, and an AI cost dashboard. Trigger.dev adds user-built dashboards and Ask Trigger.
| Feature | Trigger.dev | Inngest |
|---|---|---|
| Tracing | OpenTelemetry spans per run with structured logs | Built-in function traces with step-level detail |
| Live run updates | Runs page updates live | Function run dashboard |
| Custom queries | TRQL (SQL-style, backed by ClickHouse) | Insights : SQL over events, runs, steps, and spans (backed by ClickHouse), with saved, shared queries |
| Custom dashboards | Charts, tables, big number widgets with drag-and-drop layout | Built-in metrics and AI Overview dashboards, with Datadog and Prometheus export |
| AI query assistant | Describe what you want in plain English, generates TRQL | Insights AI generates SQL from plain English |
| Dashboard agent | Ask Trigger (beta): chat with an agent over your runs, errors, queues, and deploys for debugging, root-cause analysis, health reports, and TRQL analytics | Not available |
| AI-specific metrics | AI metrics dashboard (tokens, cost, latency per model) plus custom OTel metrics | AI Overview dashboard (tokens, cost, latency by model and function) from OpenTelemetry data |
| Prompt management | Versioned prompts with overrides, tracked per run | No built-in prompt store; experiments (group.experiment()) compare prompt or model variants on live traffic |
| Alerting | Run failure, deployment, and error-group alerts (email, Slack, webhook) | Function failure notifications |
| Trace retention | Varies by plan (see pricing ) | Varies by plan (see pricing ) |
Inngest provides built-in function traces with step-level detail, an AI Overview dashboard for LLM cost and latency, and Insights, a SQL editor over events, runs, and spans with an AI assistant that writes queries. Trigger.dev ships OpenTelemetry tracing with span-level detail, plus TRQL , an SQL-style query language backed by ClickHouse. Build custom dashboards with charts, tables, and big number widgets, or describe what you want in plain English and the AI assistant generates the query. TRQL queries are also available via SDK and REST API for programmatic access.
How do self-hosting and licensing compare?
Inngest is source-available under the SSPL (not OSI-approved), converting to Apache 2.0 three years after each release. Trigger.dev is Apache 2.0, with every release open source immediately.
| Feature | Trigger.dev | Inngest |
|---|---|---|
| License | Apache 2.0 | SSPL (converts to Apache 2.0 after 3 years) |
| OSI-approved open source | Yes | No |
| Self-hosted setup | Docker Compose or Kubernetes | inngest start (SQLite default) or Helm chart (Kubernetes with Postgres + Redis) |
| Self-hosted scale | Multi-node (Kubernetes) | Single-node (SQLite) or multi-node (Kubernetes with Postgres, KEDA autoscaling) |
| Feature parity with cloud | Core platform on the same codebase. Checkpoints (non-blocking waits), warm starts, and auto-scaling are Cloud-only | Enterprise SSO on Cloud only |
Inngest's self-hosting story starts simple: inngest start runs everything in one process with SQLite. Point it at Postgres and Redis for production, or use the Helm chart for multi-node Kubernetes deployments with KEDA autoscaling. The SSPL license allows internal use but prevents competing managed services, and enterprise SSO is a Cloud feature. Trigger.dev self-hosts on Docker Compose or Kubernetes under Apache 2.0 with the same core codebase as Cloud (checkpoints, warm starts, and auto-scaling are Cloud-only ).
Code comparison
AI document summarizer
Multi-step order processing workflow
What developers say about Trigger.dev
With Trigger.dev, we've summarized over a million student interactions in just a couple of weeks. We're incredibly thankful for tools like Trigger.dev that are empowering us to bring AI-driven solutions to educators and students at scale.

Ben Duggan

Frequently asked questions
Can I migrate from Inngest to Trigger.dev?
Yes. Inngest's
step.sleep()becomes wait utilities,step.waitForEvent()maps to Waitpoints,step.invoke()maps totriggerAndWait, and simplestep.run()blocks become inline code, because Trigger.dev resumes after waits without replay. Side effects like a payment or an email go in a subtask with a stable idempotency key , which returns its saved result if the run retries, and the payment call itself passes the provider's idempotency key.Does Inngest run my code or just orchestrate it?
Inngest orchestrates your code. It calls your app over HTTP (or a WebSocket with
connect()) to run your steps, on your own infrastructure and within that host's limits. Trigger.dev runs your code on its own managed compute with no platform-imposed timeout.I already have serverless functions. Why not just use Inngest?
If your background work always finishes inside your platform's request timeout and needs only what your serverless runtime provides, reusing your existing functions is a reasonable fit. The tradeoff is that your background jobs inherit your web app's constraints: execution timeouts, cold starts, and memory limits, and system dependencies like FFmpeg or a headless browser are packaged with your app and run within your host's limits. Trigger.dev runs background work on separate managed compute, so a job can run for minutes or hours, keep state across an AI agent's turns, and use any system dependency, without touching your web app's hosting.
Is Inngest open source?
Inngest is source-available under the SSPL, with an Apache 2.0 grant that takes effect three years after each release. The SSPL isn't OSI -approved and restricts offering Inngest as a competing hosted service, which mainly matters if you plan to resell it. Trigger.dev is Apache 2.0 from day one.
How do Inngest's platform timeouts affect my workflows?
When served from a serverless platform, Inngest steps run inside requests to your function, so they run within its timeout: 300 seconds by default on Vercel (up to 800) and 15 minutes on AWS Lambda. Inngest's
connect()mode removes the HTTP request timeout on long-running servers, up to Inngest's own 2-hour step ceiling . Trigger.dev imposes no platform timeout: you set your ownmaxDuration, or turn it off.How does Inngest's step replay work?
When a run resumes (after a wait, a retry, or parallel steps), Inngest re-enters your function from the beginning and injects memoized results for completed steps, so code outside
step.run()runs again. Inngest's TypeScript SDK checkpoints by default , running consecutive steps in one request for lower latency. Trigger.dev uses checkpoint-resume instead: after a wait your code continues where it paused without replay, and a failed run retries from the start.Which is better for AI agents: Inngest or Trigger.dev?
Inngest lets you build durable agents with any model SDK inside steps (TypeScript, Python, or Go), plus AgentKit, an optional TypeScript framework with tools, MCP support, and React hooks (
useAgent, withuseChatanduseThreadsdescribed in its docs). Agents run within the step-based execution model with automatic memoization per LLM call. Trigger.dev runs any TypeScript AI framework (AI SDK, Mastra, OpenAI Agents SDK, etc.) with no platform-imposed timeout,ai.toolExecute()to expose tasks as AI SDK tools, Realtime Streams for token streaming, input streams for sending data to running tasks, and Waitpoints for human-in-the-loop.How does pricing compare between Inngest and Trigger.dev?
Inngest charges per execution: the run itself plus every step (a function with 5
step.run()calls uses 6 executions), with a free tier of 50,000 executions per month. Trigger.dev charges per compute-second plus a per-run fee, with a free plan that includes monthly usage. Inngest's cost tracks step count (your host bills compute separately), while Trigger.dev's tracks compute time.Can I self-host Inngest?
Inngest offers self-hosting with
inngest start(SQLite by default, or Postgres and Redis for production) and a Helm chart for multi-node Kubernetes deployments with KEDA autoscaling. Trigger.dev self-hosts via Docker Compose or Kubernetes under Apache 2.0 with the same core codebase as Cloud. Checkpoints (non-blocking waits), warm starts, and auto-scaling are Cloud-only .Can I use Inngest with long-running servers instead of serverless?
Yes. Inngest's
serve()works on any HTTP server, andconnect()uses outbound WebSockets designed for long-running servers on Render, Fly.io, or Kubernetes, in TypeScript, Python, and Go. Trigger.dev runs your code on managed compute regardless of your hosting setup, so this distinction does not apply.What is the best background jobs solution for Next.js?
Inngest integrates tightly with Next.js via its
serve()adapter at/api/inngest, so background jobs ship with your app and run within your Vercel plan's function limits. Trigger.dev works with any framework including Next.js and runs tasks on separate managed compute with no platform-imposed execution timeout. A job that outgrows a request, needs FFmpeg or a browser, or runs for hours doesn't force a refactor.

