Skip to content

pgflow vs Vercel Workflows

Technical CriteriapgflowVercel Workflows
Architecture ModelDatabase-centric orchestrationCode-defined durable execution
Infrastructure RequirementsZero additional (just Supabase)Vercel platform or self-hosted “Worlds”
Workflow DefinitionTypeScript DSL with explicit dependenciesTypeScript directives ("use workflow", "use step")
Supabase IntegrationBuilt-inCan work together but requires bridging
Type SystemEnd-to-end type safetyStandard TypeScript typing
Failure HandlingAutomatic per-step retriesAutomatic per-step retries with deterministic replay
Execution StructureDatabase-driven DAGSequential async/await with automatic suspension
State ManagementInput/output data stored in PostgresManaged persistence layer (on Vercel) or custom storage
Time-based OperationsNative step delays + Supabase pg_cronBuilt-in sleep for minutes to months
Maturity LevelBeta - used in productionBeta - in active development
Monitoring ToolsSQL queries for visibilityBuilt-in dashboard on Vercel, CLI for self-hosted
WebhooksCan integrate via Supabase functionsNative webhook support with automatic URL generation
Event SystemNo built-in event systemHook-based event handling
Framework RequirementsFramework-agnosticBest with Next.js, experimental with others

Both systems provide reliable task execution with proper retries and error handling. The key difference is the orchestration model: database-driven DAG execution (pgflow) versus code-defined sequential execution with automatic suspension (Vercel Workflows).

  • Building on Supabase - You need workflow orchestration directly within your Supabase stack
  • Database-centric workflows - Your system centers around PostgreSQL operations and explicit data dependencies
  • Parallel data processing - Your workflows involve processing data with multiple parallel paths
  • SQL visibility - You want workflow state directly queryable in your database
  • Migration-based deployments - You prefer deploying workflow changes via database migrations
  • Zero infrastructure - You want to avoid adding services beyond your Supabase project
  • Platform flexibility - You need to run on any infrastructure with Postgres
  • Building on Vercel - You’re already hosting on Vercel and want integrated workflows
  • Procedural workflows - Your processes follow sequential async/await patterns
  • Long-duration pauses - You need workflows that sleep for days or months without consuming resources
  • Human-in-the-loop - Your workflows require external approvals or webhook events to continue
  • Familiar patterns - You prefer writing standard async/await code without learning DAG concepts
  • Managed infrastructure - You prefer Vercel handling queue, storage, and execution infrastructure
  • Next.js ecosystem - You’re building primarily with Next.js applications

pgflow puts PostgreSQL at the center of your workflow orchestration. Flows 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 workflow
new Flow<{ userId: string }>({
slug: 'userOnboarding',
})
.step(
{ slug: 'createUser' },
({ run }) => ({ id: crypto.randomUUID(), email: run.userId })
)
.step(
{ slug: 'sendWelcome', dependsOn: ['createUser'] },
({ createUser }) => sendEmail(createUser.email, 'Welcome!')
)
.step(
{ slug: 'sendCheckin', dependsOn: ['sendWelcome'], startDelay: 604800 },
({ createUser }) => sendEmail(createUser.email, 'How are you doing?')
);

Vercel Workflows uses code-defined directives to add durability to async functions. The "use workflow" directive marks a function as orchestrator, while "use step" marks functions that execute with full Node.js runtime. The framework handles suspension, resumption, and state persistence automatically.

// In Vercel Workflows, directives add durability to async code
import { sleep } from "workflow";
export async function userOnboarding(userId: string) {
"use workflow";
// Each step executes with automatic retries
const user = await createUser(userId);
await sendWelcomeEmail(user);
// Pause for 7 days without consuming resources
await sleep("7 days");
await sendCheckInEmail(user);
return { userId: user.id, status: "onboarded" };
}
async function createUser(userId: string) {
"use step";
// Full Node.js access - use any npm package
return { id: crypto.randomUUID(), email: userId };
}
async function sendWelcomeEmail(user: { email: string }) {
"use step";
await sendEmail(user.email, "Welcome!");
}
async function sendCheckInEmail(user: { email: string }) {
"use step";
await sendEmail(user.email, "How are you doing?");
}

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 delay step execution
  • Both store workflow state persistently
  • Both designed for serverless environments

The difference is architectural:

  • pgflow: PostgreSQL orchestrates when steps run based on dependencies compiled from TypeScript DSL
  • Vercel Workflows: Runtime orchestrates steps sequentially using directives and automatic suspension
  • 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
  • Possible integration - Can work alongside Supabase but not specifically designed for it
  • Additional infrastructure - Requires Vercel platform (managed) or custom “World” implementation (self-hosted)
  • Separate platforms - Coordinating between Vercel (frontend/workflows) and Supabase (database) adds complexity
  • State storage separation - Workflow state stored in Vercel’s managed persistence, app data in Supabase