Use Postgres for the control plane (Tier B1)¶
Audience: operators running multi-process or Compose stacks
Default remains SQLite for local zero-config.
Prefect example to borrow from: Local Prefect server — database (SQLite default; Postgres for multi-process). IronFlow uses IRONFLOW_DATABASE_URL instead of Prefect’s asyncpg URL setting; there is no ironflow server database upgrade CLI yet.
When to use it¶
- You need a networked database for the API + services process (compose default).
- HTTP workers still talk to the API, not the DB — see HTTP workers.
Setup¶
- Run Postgres 16+ and create a database/user.
- Point the API at the DSN:
export IRONFLOW_DATABASE_URL=postgresql://ironflow:ironflow@127.0.0.1:5432/ironflow
uv run python -m uvicorn python-shim.src.prefect_compat.server:app --host 127.0.0.1 --port 8000
On first connect IronFlow creates the control-plane tables (flow/task runs, deployments, workers, …).
- Leave
IRONFLOW_DATABASE_URLunset to keep the SQLite sidecar next toIRONFLOW_HISTORY_PATH.
Behavior notes¶
- Rust
bind_dbaccepts the Postgres DSN for claim / lease / mark started|finished / attach. - Schedule ticks and most CRUD use the Python path on Postgres in this slice (sqlite-shaped SQL via an adapter).
- File-mode workers that open the SQLite file directly are not a Postgres substitute — use HTTP workers for multi-process / Compose (do not share a SQLite file with the API).
See also: Docker Compose, self-hosted storage RFC, environment variables.