Featured image for Neon + Inngest: Trigger durable functions from database changes blog post

Neon + Inngest: Trigger durable functions from database changes

A new integration for Postgres database events

Dan Farrelly· 9/24/2024 · 5 min read

We're excited to announce our integration with Neon, enabling you to trigger durable functions directly from changes in your Neon Postgres database.

Neon is an open-source serverless Postgres platform that separates storage from compute, offering autoscaling and code-like database branching. Neon recently GA'd their support for logical replication which enables listening for database changes.

This new and powerful integration unlocks a wide range of use cases by decoupling triggers from your application logic, making it easier to build durable workflows.

How it works

The Neon integration enables you to connect your Neon Postgres database to your Inngest account. The initial setup can be done automatically by Inngest or you can choose a manual setup if you prefer to verify and execute the required commands yourself.

Once the initial setup is completed, any changes to data in your database will automatically send new events to your Inngest account. Here's an example event that would be created when a new row is inserted in a books table:

json
{
"name": "db/books.inserted",
"data": {
"new": {
"id": {
"data": 2,
"encoding": "i"
},
"name": {
"data": "Designing Data-Intensive Applications",
"encoding": "t"
},
"description": {
"data": "Data is at the center of many challenges...",
"encoding": "t"
}
},
"table": "books",
"txn_commit_time": "2024-09-24T14:41:19.75149Z",
"txn_id": 36530520
},
"ts": 1727146545006
}

These database events can then be used to trigger your Inngest functions. For example, you might want to run an Inngest function that creates an embedding every time a book is inserted in the books table:

inngest.createFunction(
{ id: "create-embedding-for-new-book" },
{ event: "db/books.inserted" },
async ({ event, step }) => {
const embedding = await step.run("create-embedding", async () => {
const metadata = generateMetadata(event.data.new);
return await createEmbedding(metadata);
});
await step.run("insert-embedding", async () => {
const id = event.data.new.id.data;
return await sql`UPDATE SET embedding = ${embedding} WHERE id = ${id}`
})
}
)

The end result is a simple way to trigger durable functions reacting to database changes with Inngest. You can write functions that run in response to rows being inserted, updated, or deleted from any table in your database. Functions execute in your own codebase, on your own servers, using any Inngest language SDK (TypeScript, Python, Go, or Kotlin/Java).

A powerful new trigger for functions

Leveraging events directly from your database to trigger functions provides clear benefits out of the box.

By decoupling function triggers from your application logic, events are initiated by database updates rather than relying on instrumentation in your code to send them. This ensures you won't miss an event when data is manipulated within your application. This decoupling creates a clean abstraction layer between database operations and code that runs asynchronously.

Additionally, as database events are pushed into the Inngest system to enqueue new functions, this can eliminate the need for architecture patterns like the transactional outbox pattern.

Leveraging Inngest features with database triggers

Beyond the architectural benefit, some specific Inngest features go perfectly with database triggers:

  • Fan-out - Use a single database event to trigger multiple functions to run in parallel. For example, a pg/users.inserted might trigger a welcome email function and a function that starts a trial in Stripe.
  • Batching - Database events can be batched to process many updates more efficiently. For example, many small updates can be aggregated or efficiently perform bulk operations using third party APIs that support it, like Shopify.
  • Flow control - Combine database triggers with flow control functionality like throttling, debouncing, or rate limiting for better resource management and efficiency. For example, use throttling for working with third party API rate limits or use debounce for operations that may happen frequently, helping to avoid redundant work.

This integration empowers developers to create robust, scalable systems with ease.

How to get started

Today, in your Inngest dashboard, you can find Neon in the Integrations tab. Click “Connect” to begin the setup process.

Neon integration in the Inngest dashboard

A prerequisite for setup is enabling logical replication on your Neon database, which is necessary for Inngest to stream changes from your database.

In the setup flow, Inngest will set up the users, roles and configure your database correctly. Each command that Inngest executes is visible for complete transparency. If you prefer a more hands-on approach with database administration, you can choose the manual setup, where you execute each command yourself. Throughout the process, you'll receive additional context and links to resources explaining what each command does.

Check out our Neon integration docs to learn more.

What will you build?

Neon's truly serverless Postgres gives developers a more flexible way to build with Postgres and this Inngest integration provides even more flexibility bringing durable functions to Neon. We're excited to be partnering with the Neon team and building directly with their innovative platform.

If you're a Neon user, give the integration a try today. If you're new to Neon, check out their platform, and spin up a database on their free tier. We'd love to hear what durable functions you're thinking about building with our new integration! Come chat with us and other users in our Discord today.

Help shape the future of Inngest

Ask questions, give feedback, and share feature requests

Join our Discord!