Inngest
Durable workflow and background job platform built for serverless and edge environments. Write event-driven functions with built-in retries, delays, step execution, and fan-out — no queue infrastructure needed.
Why Inngest?
Serverless functions that need multi-step workflows with retries
Event-driven background jobs without managing a queue (BullMQ needs Redis)
Long-running tasks that span multiple serverless invocations
Signal Breakdown
What drives the Trust Score
Download Trend
Last 12 months
Tradeoffs & Caveats
Know before you commitSelf-managed Redis infrastructure is fine — BullMQ is cheaper to run
Simple one-shot background tasks — a plain async function may suffice
Need complex fan-in patterns — Temporal is more powerful for very complex workflows
Pricing
Free tier & paid plans
50k function runs/mo · 3 day history
From $25/mo (Team)
Generous free tier for development
Alternative Tools
Other options worth considering
The premium queue and job scheduling solution for Node.js, backed by Redis. Handles retries, rate limiting, priorities, repeatable jobs, and job dependencies out of the box.
Often Used Together
Complementary tools that pair well with Inngest
Learning Resources
Docs, videos, tutorials, and courses
Get Started
Repository and installation options
View on GitHub
github.com/inngest/inngest
npm install inngestQuick Start
Copy and adapt to get going fast
// app/api/inngest/route.ts
import { serve } from 'inngest/next';
import { inngest } from '../../inngest/client';
import { sendWelcomeEmail } from '../../inngest/functions';
export const { GET, POST, PUT } = serve({
client: inngest,
functions: [sendWelcomeEmail],
});
// Trigger an event from anywhere
await inngest.send({ name: 'user/signup', data: { email: 'user@example.com', userId: '123' } });Code Examples
Common usage patterns
Multi-step onboarding workflow
Send a series of onboarding emails with delays
import { Inngest } from 'inngest';
const inngest = new Inngest({ id: 'my-saas' });
export const onboardingFlow = inngest.createFunction(
{ id: 'onboarding-flow', retries: 3 },
{ event: 'user/created' },
async ({ event, step }) => {
const { userId, email } = event.data;
await step.run('welcome-email', () => sendEmail(email, 'Welcome!'));
await step.sleep('day-1-wait', '1 day');
await step.run('tips-email', () => sendEmail(email, 'Here are 5 tips...'));
await step.sleep('day-6-wait', '6 days');
const user = await step.run('check-activation', () => db.user.findUnique({ where: { id: userId } }));
if (!user?.isActivated) {
await step.run('nudge-email', () => sendEmail(email, 'Still need help getting started?'));
}
}
);Fan-out: notify all team members
Trigger parallel jobs for each item in a list
export const notifyTeam = inngest.createFunction(
{ id: 'notify-team' },
{ event: 'project/created' },
async ({ event, step }) => {
const members = await step.run('get-members', () =>
db.teamMember.findMany({ where: { projectId: event.data.projectId } })
);
// Fan out — run in parallel
await Promise.all(
members.map((m) =>
step.run(`notify-${m.id}`, () => sendNotification(m.userId, event.data.projectName))
)
);
}
);Community Notes
Real experiences from developers who've used this tool