Master Inngest background job patterns for Google Antigravity IDE event-driven applications
# Inngest Background Jobs Patterns for Google Antigravity IDE
Build reliable background jobs with Inngest using Google Antigravity IDE's Gemini 3 assistance. This guide covers event-driven functions, step functions, retries, scheduling, and fan-out patterns for production workloads.
## Core Setup
```typescript
// src/inngest/client.ts
import { Inngest, EventSchemas } from "inngest";
// Define typed events
type Events = {
"user/created": {
data: {
userId: string;
email: string;
name: string;
};
};
"order/placed": {
data: {
orderId: string;
userId: string;
items: Array<{ productId: string; quantity: number; price: number }>;
total: number;
};
};
"subscription/renewed": {
data: {
subscriptionId: string;
userId: string;
planId: string;
amount: number;
};
};
"email/scheduled": {
data: {
to: string;
template: string;
variables: Record<string, unknown>;
sendAt?: string;
};
};
};
export const inngest = new Inngest({
id: "my-app",
schemas: new EventSchemas().fromRecord<Events>(),
});
```
## Step Functions for Workflows
```typescript
// src/inngest/functions/onboarding.ts
import { inngest } from "../client";
import { db } from "@/lib/db";
import { sendEmail } from "@/lib/email";
export const userOnboarding = inngest.createFunction(
{
id: "user-onboarding",
retries: 3,
onFailure: async ({ error, event }) => {
await sendSlackAlert(`Onboarding failed for ${event.data.userId}: ${error.message}`);
},
},
{ event: "user/created" },
async ({ event, step }) => {
const { userId, email, name } = event.data;
// Step 1: Create default settings
const settings = await step.run("create-settings", async () => {
return await db.userSettings.create({
data: {
userId,
theme: "dark",
notifications: true,
language: "en",
},
});
});
// Step 2: Send welcome email
await step.run("send-welcome-email", async () => {
await sendEmail({
to: email,
template: "welcome",
variables: { name, settingsUrl: `/settings/${userId}` },
});
});
// Step 3: Wait 24 hours
await step.sleep("wait-for-day-2", "24h");
// Step 4: Send tips email
await step.run("send-tips-email", async () => {
await sendEmail({
to: email,
template: "getting-started-tips",
variables: { name },
});
});
// Step 5: Wait another 3 days
await step.sleep("wait-for-day-5", "3d");
// Step 6: Check if user is active
const isActive = await step.run("check-activity", async () => {
const activity = await db.userActivity.findFirst({
where: { userId, createdAt: { gte: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000) } },
});
return !!activity;
});
// Step 7: Send re-engagement if inactive
if (!isActive) {
await step.run("send-reengagement", async () => {
await sendEmail({
to: email,
template: "we-miss-you",
variables: { name },
});
});
}
return { completed: true, stepsRun: 7 };
}
);
```
## Fan-Out Patterns
```typescript
// src/inngest/functions/order-processing.ts
export const processOrder = inngest.createFunction(
{ id: "process-order", concurrency: 10 },
{ event: "order/placed" },
async ({ event, step }) => {
const { orderId, userId, items, total } = event.data;
// Process all items in parallel
const inventoryResults = await step.run("check-inventory", async () => {
return await Promise.all(
items.map((item) =>
checkInventory(item.productId, item.quantity)
)
);
});
// Validate all items are in stock
const allInStock = inventoryResults.every((r) => r.available);
if (!allInStock) {
await step.run("notify-out-of-stock", async () => {
await sendEmail({
to: await getUserEmail(userId),
template: "out-of-stock",
variables: { orderId },
});
});
return { status: "failed", reason: "out-of-stock" };
}
// Reserve inventory
await step.run("reserve-inventory", async () => {
await Promise.all(
items.map((item) =>
reserveInventory(item.productId, item.quantity, orderId)
)
);
});
// Process payment
const payment = await step.run("process-payment", async () => {
return await stripe.paymentIntents.create({
amount: total * 100,
currency: "usd",
customer: await getStripeCustomerId(userId),
metadata: { orderId },
});
});
// Confirm payment
await step.waitForEvent("wait-payment-confirmation", {
event: "stripe/payment.succeeded",
match: "data.paymentIntentId",
timeout: "1h",
});
// Ship order
await step.run("create-shipment", async () => {
return await createShipment(orderId);
});
return { status: "completed", paymentId: payment.id };
}
);
```
## Best Practices for Google Antigravity IDE
When using Inngest with Google Antigravity, define typed events for compile-time safety. Use step functions for durable workflows. Implement onFailure handlers for alerting. Set appropriate concurrency limits. Use waitForEvent for external webhook coordination. Let Gemini 3 generate complex workflow functions from business requirements.
Google Antigravity excels at converting sequential processes into resilient step functions.This Inngest prompt is ideal for developers working on:
By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their inngest implementations.
Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.
This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.
You can modify the prompt by adding specific requirements, constraints, or preferences. For Inngest projects, consider mentioning your framework version, coding style, and any specific libraries you're using.