Learn how to run multiple Prefect server instances for high availability and load distribution
Running multiple Prefect server instances enables high availability and distributes load across your infrastructure. This guide covers configuration and deployment patterns for scaling self-hosted Prefect.
PostgreSQL version 14.9 or higher is required for multi-server deployments. SQLite does not support the features needed for state synchronization across multiple servers.
When running migrations on large database instances (especially where tables like events, flow_runs, or task_runs can reach millions of rows), the default database timeout of 10 seconds may not be sufficient for creating indexes.If you encounter a TimeoutError during migrations, increase the database timeout:
Copy
# Set timeout to 10 minutes (adjust based on your database size)export PREFECT_API_DATABASE_TIMEOUT=600# Then run the migrationprefect server database upgrade -y
For Docker deployments:
Copy
docker run -e PREFECT_API_DATABASE_TIMEOUT=600 prefecthq/prefect:latest prefect server database upgrade -y
Index creation time scales with table size. A database with millions of events may require 30+ minutes for some migrations. If a migration fails due to timeout, you may need to manually clean up any partially created indexes before retrying.
If a migration times out while creating indexes, you may need to manually complete it. For example, if migration 7a73514ca2d6 fails:
First, check which indexes were partially created:
Copy
SELECT indexname FROM pg_indexes WHERE tablename = 'events' AND indexname LIKE 'ix_events%';
Manually create the missing indexes using CONCURRENTLY to avoid blocking:
Copy
-- Drop any partial indexes from the failed migrationDROP INDEX IF EXISTS ix_events__event_related_occurred;DROP INDEX IF EXISTS ix_events__related_resource_ids;-- Create the new indexesCREATE INDEX CONCURRENTLY ix_events__related_gin ON events USING gin(related);CREATE INDEX CONCURRENTLY ix_events__event_occurred ON events (event, occurred);CREATE INDEX CONCURRENTLY ix_events__related_resource_ids_gin ON events USING gin(related_resource_ids);
Mark the migration as complete:
Copy
UPDATE alembic_version SET version_num = '7a73514ca2d6';
Only use manual recovery if increasing the timeout and retrying the migration doesn’t work. Always verify the correct migration version and index definitions from the migration files.