Running Background Jobs on Vercel: Inngest vs Trigger.dev
Vercel's serverless functions time out at 10 seconds on Hobby tier, 60 seconds on Pro. Your PDF generation takes 45 seconds. Your data sync runs for 5 minutes. Your batch email send processes 10,000 records over 8 minutes.
January 8, 2025 11 min read
Vercel's serverless functions time out at 10 seconds on Hobby tier, 60 seconds on Pro. Your PDF generation takes 45 seconds. Your data sync runs for 5 minutes. Your batch email send processes 10,000 records over 8 minutes.
Serverless execution limits break traditional background job patterns. You cannot run long-running tasks in serverless functions without hitting timeouts and failed requests.
Two tools solve this specifically for Vercel deployments: Inngest and Trigger.dev. Both extend serverless functions beyond execution limits. Both handle retries, scheduling, and complex workflows. They differ in pricing, developer experience, and architecture.
The Serverless Background Job Problem
Traditional background job systems (Sidekiq, Bull, Celery) assume long-running server processes. They poll job queues continuously and execute tasks that run for minutes or hours. For a deeper understanding of serverless infrastructure, see our guide to Vercel deployment beyond basics.
Serverless functions execute briefly and shut down. This is the point - you pay only for execution time, not idle time. But it creates challenges for background work:
Execution time limits:
Vercel Hobby: 10 seconds max
Vercel Pro: 60 seconds max (300 seconds in specific regions)
On traditional servers, you use Redis-backed queues (Bull, Sidekiq) or database-backed queues (Postgres with pg-boss). On serverless, you need purpose-built infrastructure.
Inngest: The Event-Driven Approach
Inngest treats background jobs as event-driven functions. You define functions that react to events. Inngest handles scheduling, retries, and execution orchestration.
How Inngest Works
Define functions in your Next.js API routes
Send events from anywhere in your application
Inngest triggers functions based on event matching
Functions run with retries, timeouts, and observability built-in
Code example:
Each step.run() is independently retried if it fails. If step 2 fails, steps 1 and 3 do not rerun.
Inngest Pricing
Free tier (Development):
Unlimited events
Unlimited functions
Limited to development environment
Full feature access
Startup tier ($40/month):
1 million steps per month included
$0.00004 per additional step
Production environment
30-day event history
Email support
Team tier ($175/month):
5 million steps included
$0.000035 per additional step
90-day event history
Slack support
Enterprise tier (custom):
Volume pricing
Dedicated infrastructure
SOC 2 compliance
SLAs
Step-based pricing explained: A "step" is each step.run() execution. If your function has 3 steps and runs 100,000 times, that is 300,000 steps.
For most startups, Startup tier ($40/month) covers significant scale. 1 million steps = roughly 250,000-500,000 function executions with 2-4 steps each.
Developer Experience
Inngest integrates seamlessly with Next.js:
Install inngest package
Create API route at /api/inngest
Define functions in your codebase
Deploy to Vercel (Inngest auto-discovers functions)
The API is TypeScript-first with excellent type inference. Events are typed, function parameters are typed, step return values are typed.
Local development works via Inngest Dev Server - run locally and see events flow through the system with full observability.
Key Features
Automatic retries: Configure retry count and backoff strategy per function. Inngest handles exponential backoff automatically.
Step-based execution: Break functions into steps. Each step is atomic and retried independently.
Delays and scheduling: Run functions after delays (step.sleep()), or schedule recurring jobs (cron syntax).
Concurrency control: Limit how many instances of a function run simultaneously.
Throttling: Rate-limit function execution (max 100 per minute, etc.).
Event batching: Process multiple events in batches rather than one-by-one.
Observability: Dashboard shows function runs, step execution, failures, and logs.
When Inngest Makes Sense
Modern Next.js stacks: Inngest is built for Next.js serverless deployments. The integration is native and frictionless.
Event-driven architectures: If your application logic is naturally event-driven (user signed up → trigger 5 things), Inngest fits perfectly.
Need for step-based workflows: Complex multi-step jobs benefit from Inngest's step isolation and retry granularity.
Predictable costs: Step-based pricing is transparent. Calculate costs based on function complexity and execution frequency.
Trigger.dev provides long-running job execution infrastructure. Jobs can run for hours, use significant memory, and are not constrained by serverless limits.
How Trigger.dev Works
Define jobs in your codebase using Trigger.dev SDK
Trigger jobs from API routes, webhooks, or schedules
Trigger.dev executes jobs on dedicated infrastructure (not Vercel functions)
Jobs run to completion regardless of duration
Code example:
Jobs run on Trigger.dev's infrastructure, not Vercel's serverless functions. This removes execution time limits entirely.
Trigger.dev Pricing
Free tier (Development):
Unlimited job runs
Development environment only
Full feature access
Community support
Startup tier ($20/month):
500 job runs per month included
$0.04 per additional run
Production environment
30-day retention
Email support
Pro tier ($100/month):
5,000 job runs included
$0.02 per additional run
90-day retention
Priority support
Advanced monitoring
Enterprise tier (custom):
Volume pricing
Dedicated infrastructure
SOC 2 compliance
SLAs
Run-based pricing explained: A "run" is a complete job execution, regardless of how long it takes or how many tasks it contains.
For complex jobs with many steps, Trigger.dev can be cheaper than Inngest's step-based pricing. For simple jobs, Inngest is often cheaper.
Developer Experience
Trigger.dev integration is straightforward:
Install @trigger.dev/sdk and @trigger.dev/nextjs
Create API route for Trigger.dev webhook
Define jobs in /trigger directory
Deploy and jobs are automatically registered
The CLI (trigger.dev dev) runs a local development environment where you can test jobs before deployment.
TypeScript support is solid. Payload types are inferred, task return types flow through, and autocomplete works well.
Key Features
No execution time limits: Jobs run until completion. We have run jobs that take 2+ hours without issues.
High memory allocation: Jobs can use more memory than Vercel functions allow.
Winner: Inngest by $3,960/month for high-frequency jobs.
Architecture Considerations
Where Code Runs
Inngest: Functions execute as Vercel serverless functions. You deploy to Vercel normally. Inngest orchestrates when and how they run but the execution happens in your Vercel environment.
Trigger.dev: Jobs execute on Trigger.dev's infrastructure. Your Vercel deployment triggers jobs, but Trigger.dev runs them on dedicated machines.
This difference matters for:
Latency: Inngest functions run where your app runs (fast access to database). Trigger.dev jobs run separately (potential network latency to database).
Security: Inngest code runs in your environment with your secrets. Trigger.dev code runs in their environment (you provide secrets via their dashboard).
Vendor dependency: Inngest orchestrates, you execute. Trigger.dev both orchestrates and executes (higher vendor lock-in).
State and Persistence
Inngest: Function state is managed by Inngest's event log. Steps are checkpointed automatically.
Trigger.dev: Task state is managed by Trigger.dev's infrastructure. Full execution context is preserved.
Both handle retries intelligently - failed steps/tasks rerun without redoing successful work.
Database Access
Inngest functions run in your Vercel environment, so database access uses your normal connection strings. No additional latency or security configuration needed.
Trigger.dev jobs run remotely, so they need database connection strings passed as secrets. If your database is private (not publicly accessible), you must expose it or use connection proxies.
For Convex-based applications, both tools work well since Convex exposes public APIs with authentication.
Hybrid Approaches
You can use both tools in the same application:
Inngest for:
High-frequency jobs (webhooks, user actions)
Short-duration multi-step workflows
Event-driven patterns
Trigger.dev for:
Long-running exports and reports
High-memory batch processing
Jobs exceeding 60 seconds
This hybrid approach optimizes costs and capabilities.
Migration Considerations
Switching between Inngest and Trigger.dev requires rewriting job definitions. The concepts are similar but APIs differ.
Migration effort:
Rewrite job definitions: 30 minutes to 2 hours per job
Update trigger points in application: 1-4 hours
Test all jobs in new system: 2-8 hours
Monitor in production: Ongoing for 1-2 weeks
Total: 8-20 hours for moderately complex applications with 5-10 background jobs.
Neither tool makes migration particularly hard, but it is not trivial either.
Our Recommendation
Default choice for most Next.js apps: Inngest. Better pricing for typical job patterns, native Next.js integration, excellent developer experience.
Choose Trigger.dev when:
Jobs regularly exceed 60 seconds execution time
Jobs require >1 GB memory
Per-run pricing is cheaper for your pattern (few complex jobs)
You need pre-built integrations Trigger.dev offers
Use both when:
You have distinct job types (frequent short jobs + occasional long jobs)
Optimizing costs matters enough to justify managing two systems
For most MVP development projects, Inngest covers all background job needs within Vercel's constraints.
Serverless Background Jobs vs Traditional Queues
If you are on traditional infrastructure (long-running servers), you might not need either tool.
Use traditional queues (Bull, Sidekiq, BullMQ) when:
You control server infrastructure (EC2, VPS, Kubernetes)
Jobs are extremely high frequency (millions per day)
You need maximum cost optimization at scale
Use serverless-specific tools (Inngest, Trigger.dev) when:
Deploying to Vercel, Netlify, or similar serverless platforms
You want zero infrastructure management
Usage is moderate (<1M jobs per month)
Traditional queues are cheaper at very high scale but require you to manage servers, Redis, monitoring, and deployment infrastructure.
Key Takeaways
Background jobs on serverless require purpose-built tools because of execution time and state limitations:
Inngest: Event-driven functions, step-based pricing, excellent for high-frequency short jobs. $40/month covers most startup needs.
Trigger.dev: Long-running jobs, per-run pricing, removes time limits entirely. $20/month base, costs scale with job count.
Cost model: Inngest charges per step, Trigger.dev per run. Choose based on job frequency and complexity.
Architecture: Inngest runs in your environment, Trigger.dev runs on their infrastructure.
For typical Next.js SaaS applications with user-triggered workflows, Inngest is the better default. For data-heavy operations exceeding serverless limits, Trigger.dev solves problems Inngest cannot.
Both are vastly better than trying to force traditional background job patterns into serverless constraints.
Most marketing automation apps treat AI as a feature to add later. Here's why that approach fails—and how to architect AI-native marketing automation from day one.