Skip to content

# How pgflow Works

pgflow runs multi-step workflows (flows) on Supabase with automatic parallelization, retries, and dependency tracking. This page shows how it works.

This flow demonstrates three key behaviors:

🔀 Parallel execution - `summarize` and `extractKeywords` start immediately after `fetchArticle` completes.

🔄 Automatic retry - When `summarize` fails, pgflow retries automatically.

🔗 Dependency coordination - `publish` waits for both steps to complete.

Two tasks run in parallel. One fails and automatically retries. After both succeed, they trigger the final publish step.

Now let’s understand what happens under the hood.

## How pgflow Makes This Possible

Section titled “How pgflow Makes This Possible”

At its core, pgflow does two things:

1. 🧠 Figures out which steps are ready based on dependencies
2. 📤 Pushes tasks into queues for workers to execute

Workers pull from these queues and run your functions.

Key Separation

pgflow handles orchestration (what to run, when)

You handle business logic (how to process data)

## From Code to Execution

Section titled “From Code to Execution”

🔨 Build-time: Write workflows in TypeScript, compile to SQL migrations

⚡ Run-time: Postgres orchestrates (determines what runs when), workers execute your functions

All workflow state lives in Postgres tables - giving you full observability.

## Defining the Workflow

Section titled “Defining the Workflow”

Workflows are built by chaining `.step()` calls. Each step has a unique slug (identifier) and declares which steps it dependsOn:

    new Flow<Input>({ slug: "process_article" })  .step({ slug: "fetchArticle" }, fn)  .step({ slug: "summarize", dependsOn: ["fetchArticle"] }, fn)  .step({ slug: "extractKeywords", dependsOn: ["fetchArticle"] }, fn)  .step({ slug: "publish", dependsOn: ["summarize", "extractKeywords"] }, fn);

pgflow uses dependencies to figure out execution order and parallelism. Steps with the same dependencies run in parallel. Return values become available as `input.<slug>` to dependent steps.

See full code

    type Input = { url: string };
    new Flow<Input>({ slug: "process_article" })  .step(    { slug: "fetchArticle" },    async (input) => {      const response = await fetch(input.run.url);      return response.text();    }  )  .step(    { slug: "summarize", dependsOn: ["fetchArticle"] },    async (input) => {      return await openai.summarize(input.fetchArticle);    }  )  .step(    { slug: "extractKeywords", dependsOn: ["fetchArticle"] },    async (input) => {      return await openai.extractKeywords(input.fetchArticle);    }  )  .step(    { slug: "publish", dependsOn: ["summarize", "extractKeywords"] },    async (input) => {      await db.insert({        summary: input.summarize,        keywords: input.extractKeywords      });    }  );

## Deploy as Edge Function

Section titled “Deploy as Edge Function”

No Deno.serve boilerplate - three lines sets up a persistent worker:

    import { EdgeWorker } from "jsr:@pgflow/edge-worker";import ProcessArticle from './process_article.ts';
    EdgeWorker.start(ProcessArticle);

Continuous Workers

pgflow workers use Supabase Background Tasks and add automatic respawning, continuous polling, and heartbeats for ease of use, continuity, observability, and <100ms task startup. How it works →

## Start Your Flow

Section titled “Start Your Flow”

Trigger a run from SQL:

    SELECT pgflow.start_flow(  flow_slug => 'process_article',  input => '{"url": "https://example.com"}'::jsonb);

Since it’s a SQL function, call it anywhere: schedule with `pg_cron`, use in db triggers, within transactions, from your app via Supabase RPC, or use the pgflow client for realtime updates.

That’s it - dependencies determine execution order, pgflow handles parallelism and retries, all state lives in Postgres.

## Learn More

Section titled “Learn More”
Install pgflow Set up pgflow in your Supabase project with one command
Create your first flow Build a simple workflow to see how steps connect
Monitor Execution Query step states, view execution timeline, troubleshoot failures
Three-layer architecture Deep dive into three-layer separation and design philosophy

## Join the Community

Connect on Discord

Have questions or need help? pgflow is just getting started - join us on Discord to ask questions, share feedback, or discuss partnership opportunities.

##### Join Discord →