Slackbot
08/27/2025, 10:11 AMMarvin
08/27/2025, 10:11 AMMarvin
08/27/2025, 10:11 AMMarvin
08/27/2025, 10:13 AMFROM prefecthq/prefect:3-latest
RUN pip install --no-cache-dir asyncpg
Then run your container with:
-e PREFECT_SERVER_DATABASE_CONNECTION_URL="<postgresql+asyncpg://user:pass@host:5432/dbname>"
- Or inline install on container start (handy for testing):
docker run --rm \
-e PREFECT_SERVER_DATABASE_CONNECTION_URL="<postgresql+asyncpg://user:pass@host:5432/dbname>" \
prefecthq/prefect:3-latest \
sh -c "pip install --no-cache-dir asyncpg && prefect server start"
Config env var
- Preferred in Prefect 3.x: PREFECT_SERVER_DATABASE_CONNECTION_URL
- PREFECT_API_DATABASE_CONNECTION_URL
is also recognized for compatibility
- Settings reference: Prefect 3 settings reference
- Self-hosting overview: Self-hosted Prefect 3 guide
If you’re still seeing the same error:
- Please share the exact connection URL you’re using (mask credentials), how you’re setting it (env var name), and how you’re starting the container. The error string specifically showing postgres.asyncpg strongly suggests the URL ended up as postgres+asyncpg somewhere, so double-check the spelling and that the env var is actually being picked up by the container.Marvin
08/27/2025, 10:14 AMpostgresql+asyncpg
and have the asyncpg
package installed in the container. The error you’re seeing (sqlalchemy.dialects:postgres.asyncpg
) usually means either:
- the URL starts with postgres+asyncpg://...
(wrong) instead of postgresql+asyncpg://...
(right), or
- asyncpg
is not installed in the image.
What to do:
1) Use the correct connection URL
- Env var: PREFECT_API_DATABASE_CONNECTION_URL
- Format: <postgresql+asyncpg://user:pass@host:5432/dbname>
Example:
PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect@db:5432/prefect>
2) Ensure asyncpg is installed in the container
The official prefect:3-latest
image doesn’t bundle asyncpg
. Add it yourself:
- Dockerfile (recommended)
FROM prefecthq/prefect:3-latest
RUN pip install --no-cache-dir asyncpg
- Or in docker-compose as a quick test
services:
prefect:
image: prefecthq/prefect:3-latest
environment:
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect@db:5432/prefect>
command: /bin/sh -c "pip install -q asyncpg && prefect server start"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
Quick checks:
- Inside the running container:
python -c "import asyncpg; print('asyncpg OK')"
prefect config view | grep PREFECT_API_DATABASE_CONNECTION_URL
Docs:
- Prefect 3 settings reference
- Database configuration for Prefect Server
If you share the exact URL you’re using and how you’re launching the container (compose, k8s, etc.), I can spot-check it.Denys Y
08/27/2025, 11:30 AMMarvin
08/27/2025, 11:32 AMMarvin
08/27/2025, 11:34 AMPREFECT_API_DATABASE_CONNECTION_URL=sqlite+aiosqlite:////absolute/path/to/prefect.db
- SQLite (file, relative to current working directory: 3 slashes):
PREFECT_API_DATABASE_CONNECTION_URL=sqlite+aiosqlite:///relative/path/prefect.db
- SQLite (shared in‑memory URI):
PREFECT_API_DATABASE_CONNECTION_URL=sqlite+aiosqlite:///file::memory:?cache=shared&uri=true
- PostgreSQL (asyncpg):
PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://username:password@hostname:5432/dbname>
- PostgreSQL with SSL enabled (asyncpg uses ssl, not sslmode):
PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://username:password@hostname:5432/dbname?ssl=true>
Common pitfalls to check
- Use async drivers:
- SQLite: sqlite+aiosqlite
- Postgres: postgresql+asyncpg
- Synchronous drivers like psycopg/psycopg2 are not supported for the 3.x API.
- SQLite slashes:
- Absolute path: 4 slashes after the driver (…://///abs/path.db)
- Relative path: 3 slashes (…:///relative/path.db)
- Credential characters: If your username/password contains special chars (@, :, /, ?), percent‑encode them or use an alternative auth mechanism/secret injection.
- SSL parameter: For asyncpg use ssl=true
(not sslmode=require
, which applies to libpq/psycopg).
- Environment expansion: ${PREFECT_HOME}
will only resolve if your environment expands it before Prefect reads it (e.g., in a shell with double quotes). Otherwise, provide a concrete absolute path.
- Example (Bash):
export PREFECT_HOME=/opt/prefect
export PREFECT_API_DATABASE_CONNECTION_URL="sqlite+aiosqlite:///${PREFECT_HOME}/prefect.db"
- Privileges: For Postgres, ensure the DB user can create/alter tables (Prefect runs migrations on startup).
Notes vs Prefect 2.x
- The variable name is the same (PREFECT_API_DATABASE_CONNECTION_URL
).
- In 3.x the API still requires async drivers; sticking to +aiosqlite
and +asyncpg
is the safe path.
If you want me to sanity‑check your exact URL, paste it here with secrets redacted and tell me which database you’re targeting.
References
- Settings reference: Prefect 3.x settings reference
- Self-hosting guide: Self-hosted Prefect (DB configuration)Denys Y
08/27/2025, 11:44 AMMarvin
08/27/2025, 11:44 AMMarvin
08/27/2025, 11:48 AMPREFECT_SERVER_DATABASE_CONNECTION_URL=<postgresql+asyncpg://username:password@hostname:5432/dbname>
- If your Postgres requires TLS, add it (example):
PREFECT_SERVER_DATABASE_CONNECTION_URL=<postgresql+asyncpg://username:password@hostname:5432/dbname?sslmode=require>
- Timeouts and “wal_exec”
- “wal_exec” sounds like a Postgres wait around WAL write/flush pressure. During initial startup Prefect runs migrations and creates indexes which can be write-heavy; if the database storage is slow or under-provisioned, queries can hit client timeouts.
- Prefect’s defaults are fairly short (e.g., ~5s connection timeout, ~10s statement timeout). If the DB is slow to respond under WAL pressure, you’ll see timeouts even though the DB is “up”.
- Things to try
- Increase Prefect’s DB timeouts:
PREFECT_SERVER_DATABASE_TIMEOUT=30
PREFECT_SERVER_DATABASE_CONNECTION_TIMEOUT=15
PREFECT_SERVER_DATABASE_SQLALCHEMY_POOL_TIMEOUT=60
- Ensure network and security groups allow traffic and latency is low between the Prefect API and Postgres.
- If using PgBouncer/RDS Proxy, verify it’s in session pooling mode for asyncpg or disable prepared statement caching; transaction pooling plus prepared statements can cause odd behavior (usually different errors, but still worth checking).
- Check Postgres for WAL/disk pressure (RDS Performance Insights / pg_stat_activity wait events). If WAL waits are frequent, consider increasing storage IOPS/throughput or running migrations during off-peak.
Can you share:
- Your Prefect version (2.x vs 3.x)
- The exact timeout error text and where it appears (API logs vs DB logs)
- Whether you’re behind PgBouncer/Proxy and your Postgres version/host (RDS, Cloud SQL, etc.)
Docs:
- Prefect 3 self-hosted server
- Settings reference