Skip to content

# pgflow vs Inngest

## Features

Section titled “Features”

Technical Criteria | pgflow | Inngest
--- | --- | ---
Architecture Model | Database-centric orchestration | Durable execution engine
Infrastructure Requirements | Zero additional (just Supabase) | Hosted service or self-hosted
Workflow Definition | TypeScript DSL with explicit dependencies | Step-based functions with checkpoints
Supabase Integration | Built-in | Requires manual configuration
Type System | End-to-end type safety | Standard TypeScript typing
Failure Handling | Automatic per-step retries | Automatic per-step retries
Execution Structure | Database-driven DAG | Linear step-by-step with state persistence
State Management | Input/output data stored in database | Input/output memoized in execution service
Time-based Operations | Via Supabase pg_cron | Built-in sleep and waitForEvent capabilities
Maturity Level | Active development | Production-ready
Monitoring Tools | SQL queries for visibility | Comprehensive web dashboard
Concurrency Management | Simple per-flow limits | Advanced throttling and concurrency controls
Event System | No built-in event system | Rich event-driven architecture

Both systems provide reliable task execution with proper retries and error handling. The key difference is who controls the workflow orchestration: the database (pgflow) or a durable execution engine (Inngest).

## When to Choose

Section titled “When to Choose”

### pgflow

Section titled “pgflow”

- Supabase-native solution - You need workflow orchestration directly within your Supabase stack
- Transparent state storage - You want workflow state directly visible and queryable in your database
- Parallel data processing - Your workflows involve processing data with multiple parallel paths
- Database-centric ecosystem - Your system already centers around PostgreSQL operations
- Explicit data dependencies - Your processes have clear input/output relationships between steps
- Migration-based deployments - You prefer deploying workflow changes via database migrations
- Minimal infrastructure - You want to avoid adding services beyond your Supabase project

### Inngest

Section titled “Inngest”

- Event-driven systems - You’re building applications centered around events and reactions
- Temporal workflows - You need sequences that wait for time or external events before continuing
- Sequential steps - Your processes follow linear paths with checkpointing
- UI visibility need - You need a dedicated dashboard for monitoring workflow executions
- Multi-environment deployment - You need to run the same workflows across different platforms
- Sleep/wait mechanics - Your workflows pause for specific time periods or external triggers
- Throttling requirements - You need sophisticated rate limiting for external API calls

## Code Examples

Section titled “Code Examples”

### pgflow

Section titled “pgflow”

pgflow puts PostgreSQL at the center of your workflow orchestration. Workflows are defined in TypeScript but compiled to SQL migrations with all orchestration logic running directly in the database. The database decides when tasks are ready to execute based on explicit dependencies.

    // In pgflow, the database orchestrates the workflownew Flow<{ url: string }>({  slug: 'analyze_website',})  .step(    { slug: 'extract' },    async (input) => /* extract data */  )  .step(    { slug: 'transform', dependsOn: ['extract'] },    async (input) => /* transform using extract results */  );

### Inngest

Section titled “Inngest”

Inngest uses a durable execution engine to orchestrate workflows. Functions are defined as a series of steps, where each step is a checkpoint that can be retried independently. The execution engine tracks state and resumes execution from the last successful step.

    // In Inngest, steps define checkpoints within a functionimport { Inngest } from "inngest";
    const inngest = new Inngest({ id: "my-app" });
    export default inngest.createFunction(  { id: "analyze-website" },  { event: "app/website.analyze" },  async ({ event, step }) => {    // Each step is retried independently    const extracted = await step.run("extract", async () => {      return await extractData(event.data.url);    });
        // State is automatically passed between steps    const transformed = await step.run("transform", async () => {      return await transformData(extracted);    });
        // Return the final result    return { data: transformed };  });

## Similarities

Section titled “Similarities”

Both systems provide reliable execution of workflow tasks:

- Both handle retries and error recovery
- Both track execution state and progress
- Both provide type safety
- Both can process steps asynchronously
- Both store the state of workflow executions

The difference is architectural:

- pgflow: PostgreSQL orchestrates when steps run based on dependencies
- Inngest: Execution engine orchestrates steps sequentially with state memoization

## Integration with Supabase

Section titled “Integration with Supabase”

### pgflow

Section titled “pgflow”

- Native integration - Built specifically for Supabase ecosystem
- Zero infrastructure - Uses Supabase Edge Functions and PostgreSQL
- Simple setup - Single command (`npx pgflow install`) sets up all required components
- Direct database access - All workflow state directly accessible in your Supabase database

### Inngest

Section titled “Inngest”

- Possible integration - Can work with Supabase but not specifically designed for it
- Additional infrastructure - Requires either hosted service or self-hosted instance
- Event bridging - Requires connecting Supabase events to Inngest’s event system
- Separate state storage - Workflow state stored outside your Supabase database