This release fixes a critical authentication issue where ensure_workers() fails to start Edge Workers due to key format mismatches, resulting in 401 Unauthorized errors. This resolves GitHub issue #603.
Supabase stores the service role key in different formats depending on where you access it:
In Vault (used by ensure_workers): JWT format starting with eyJhbG...
In Edge Functions (SUPABASE_SERVICE_ROLE_KEY env var): Internal format starting with sb_secret_...
When ensure_workers sends an HTTP request to trigger a worker, it includes the JWT-format key from vault in the Authorization header. However, the Edge Worker validates this against SUPABASE_SERVICE_ROLE_KEY, which contains the sb_secret_... format. Since these strings don’t match, authentication fails with a 401 error.
For backwards compatibility, pgflow falls back to the legacy secrets if PGFLOW_AUTH_SECRET is not configured:
Database side: Falls back to supabase_service_role_key in vault
Edge Function side: Falls back to SUPABASE_SERVICE_ROLE_KEY env var
Existing deployments will continue to work without immediate changes, though we strongly recommend migrating to PGFLOW_AUTH_SECRET to avoid the format mismatch issues.
When a worker crashes or is terminated unexpectedly, tasks can get stuck in started status indefinitely. These “stalled” tasks never complete and block flow progress. This was reported in #586.
If local development stopped working after a Supabase CLI update, this release fixes it.
pgflow now detects local development by checking the SUPABASE_URL environment variable. When running locally, Supabase CLI sets this to http://kong:8000 (the Docker-internal API gateway). This is more reliable than the previous key-based detection, which broke when Supabase CLI transitioned to new opaque API keys.
Previously, every time a downstream step needed its dependency’s output, pgflow ran an aggregation query:
SELECT jsonb_agg(outputORDER BYindex)
FROMpgflow.step_tasks
WHERE run_id = $1AND step_slug = $2
For a Map step with 500 items, this query scanned 500 rows. When another Map step depended on it with 500 tasks, that’s 500 tasks x 500 rows = 250,000 row scans.
This release includes a data migration that backfills step_states.output for existing completed steps.
Test locally with production data
Download a production backup and restore it locally to test the migration. See Restoring a downloaded backup in the Supabase docs, then run npx supabase db push to test the migration.
Record enabled worker functions
Before disabling, note which functions are currently enabled:
This change stores step outputs in a queryable location - a prerequisite for conditional execution. Future releases will use these stored outputs to evaluate conditions and skip steps dynamically.
pgflow 0.12.0 introduces asymmetric handler signatures - a breaking change that removes the run wrapper from step inputs, enabling cleaner functional composition and preparing the foundation for subflows.
pgflow 0.11.0 introduces a redesigned compilation configuration system. The new compilation option provides clearer semantics and adds support for rapid iteration platforms like Lovable through the allowDataLoss flag.
pgflow 0.10.0 is a developer experience milestone. This release eliminates two of the biggest friction points in pgflow development: manual flow compilation and worker lifecycle management.
Previously, every flow change required running pgflow compile, dropping old flow data with ‘pgflow.delete_flow_and_data()’ and migrating database, all before you can test your flow. This release introduces automatic flow compilation and previous version deletion that happens when workers start.
Managing worker lifecycles on hosted Supabase has been a pain point. Edge Functions have CPU time limits, worker contantly respanw themselves for continuos operation and to make it reliable one needed to setup a manual cron schedule.
pgflow 0.10.0 introduces built-in worker management that handles all of this automatically.
pgflow now sets up the pgflow_ensure_workers cron automatically during migration. If you previously set up manual cron jobs to keep workers running (from older documentation), remove them:
connectionString now works (#469, #424) - The connectionString config option was being ignored. Now it works, enabling patterns like falling back to SUPABASE_DB_URL.
Pass raw postgres.js connection - Use config.sql to pass your own postgres.js instance with custom options (SSL, connection pooling, etc.).
Zero-config local dev - When local environment is detected (via known local dev keys), the worker automatically connects to the local transaction pooler. No environment variables needed.
Cleaner install - pgflow install no longer writes EDGE_WORKER_DB_URL to .env since local dev works without it.
This release was shaped by community feedback. Thanks to Nciso, mikz, ddlaws0n, and PixelEcho (Discord) for reporting issues, suggesting improvements, and helping improve the documentation.
This simplifies the development setup and lays groundwork for future auto-compilation features where workers will verify and compile flows at startup without any CLI involvement.
The --deno-json flag has been removed. Compilation now uses the ControlPlane
edge function instead of local Deno. If you used this flag in CI/CD scripts,
update them to use the new compilation approach.
pgflow 0.8.0 requires pgmq 1.5.0 or higher and PostgreSQL 17. This release removes the pgmq compatibility layer and prepares the foundation for upcoming flow auto-compilation features.
This release skips backward compatibility entirely - pgflow 0.8.0 requires pgmq 1.5.0 from the start. Maintaining compatibility layers for older versions would accumulate technical debt that becomes harder to remove as the project matures.
Additionally, upcoming features like flow auto-compilation depend on infrastructure available only in newer Supabase versions (automatic edge function respawning in local development). Moving to pgmq 1.5.0 and PostgreSQL 17 unblocks these improvements.
The migration includes a pre-check that inspects the pgmq schema before making any changes. If pgmq 1.5.0 is not detected, the migration aborts with this error:
ERROR: INCOMPATIBLE PGMQ VERSION DETECTED
This migration requires pgmq 1.5.0 or higher.
The pgmq.message_record type is missing the "headers" column,
which indicates you are running pgmq < 1.5.0.
Action required:
- Supabase: Ensure you are running a recent version that includes pgmq 1.5.0+
- Self-hosted: Upgrade pgmq to version 1.5.0 or higher before running this migration
Migration aborted to prevent runtime failures.
This safety check prevents partial migrations and data corruption.
pgflow 0.7.3 introduces a configurable realtimeStabilizationDelayMs option that addresses a known Supabase Realtime limitation where backend routing isn’t fully established when the SUBSCRIBED event is emitted.
The TypeScript client now includes a realtimeStabilizationDelayMs configuration option (default: 300ms) that adds a delay after subscribing to Realtime channels. This works around a known Supabase Realtime issue where messages sent immediately after subscription confirmation may be missed because backend routing takes additional time to fully establish.
When starting flows or retrieving runs, the client waits for this stabilization period after receiving the SUBSCRIBED event, ensuring that all subsequent realtime events are properly received.