Background Jobs

Durable background functions with Inngest

Background Jobs

Eden Stack uses Inngest for durable background functions. Jobs survive server restarts, automatically retry on failure, and can be scheduled or delayed.

Setup

The Inngest client is configured in @eden/jobs:

import { inngest } from "@eden/jobs";

Required environment variable for production:

INNGEST_EVENT_KEY=your-event-key
INNGEST_SIGNING_KEY=your-signing-key

Creating Functions

Define a background function in packages/jobs/src/functions.ts:

import { inngest } from "./index";
 
export const sendWelcomeEmail = inngest.createFunction(
  { id: "send-welcome-email" },
  { event: "user/created" },
  async ({ event, step }) => {
    const { userId, email } = event.data;
 
    // Steps are automatically retried on failure
    await step.run("send-email", async () => {
      await sendEmail({
        to: email,
        subject: "Welcome!",
        template: <WelcomeEmail />,
      });
    });
 
    await step.run("update-user", async () => {
      await db
        .update(users)
        .set({ welcomeEmailSent: true })
        .where(eq(users.id, userId));
    });
  }
);

Sending Events

Trigger a background job by sending an event:

import { inngest } from "@eden/jobs";
 
// In your API route after user signup
await inngest.send({
  name: "user/created",
  data: {
    userId: newUser.id,
    email: newUser.email,
  },
});

Common Patterns

Delayed Jobs

Run a job after a delay:

inngest.createFunction(
  { id: "send-reminder" },
  { event: "reminder/scheduled" },
  async ({ event, step }) => {
    // Wait 24 hours
    await step.sleep("wait-24h", "24h");
 
    await step.run("send-reminder", async () => {
      // Send the reminder
    });
  }
);

Scheduled Jobs (Cron)

Run on a schedule:

inngest.createFunction(
  { id: "daily-report" },
  { cron: "0 9 * * *" }, // 9 AM daily
  async ({ step }) => {
    await step.run("generate-report", async () => {
      // Generate and send daily report
    });
  }
);

Fan-out

Process multiple items in parallel:

inngest.createFunction(
  { id: "process-batch" },
  { event: "batch/process" },
  async ({ event, step }) => {
    const items = event.data.items;
 
    // Process all items in parallel
    await Promise.all(
      items.map((item) =>
        step.run(`process-${item.id}`, () => processItem(item))
      )
    );
  }
);

Local Development

Run the Inngest dev server:

npx inngest-cli@latest dev

This opens a dashboard at http://localhost:8288 where you can:

  • View function definitions
  • See event history
  • Trigger test events
  • Debug failed runs

Production Setup

  1. Create an account at inngest.com
  2. Create an app and get your keys
  3. Set environment variables
  4. Deploy your API with the Inngest serve endpoint

The serve endpoint is already configured in your Elysia app.

Next Steps

Full documentation for Eden Stack users

This documentation is exclusively available to Eden Stack customers. Already purchased? Log in to access the full content.