Skip to content

Database & Redis

MediaFusion uses PostgreSQL as the primary database and Redis for caching, task queuing, and rate limiting.

PostgreSQL

Variable Default Description
POSTGRES_URI required Primary read-write connection string
POSTGRES_READ_URI None Optional read-replica URI. If set, read queries route here.
POSTGRES_USE_PGBOUNCER false Set true when POSTGRES_URI points at PgBouncer in transaction mode
DB_MAX_CONNECTIONS 50 Total SQLAlchemy connection budget per instance

Connection string formats

Both formats are accepted — the backend normalises them automatically:

# Standard format
POSTGRES_URI=postgresql://user:password@host:5432/mediafusion

# SQLAlchemy format (also accepted)
POSTGRES_URI=postgresql+asyncpg://user:password@host:5432/mediafusion

Connection pool sizing

DB_MAX_CONNECTIONS is divided by GUNICORN_WORKERS and by 2 if POSTGRES_READ_URI is set.

For example: DB_MAX_CONNECTIONS=50, GUNICORN_WORKERS=3, with read replica → each worker gets 50 / 3 / 2 ≈ 8 connections.

If you see QueuePool limit ... connection timed out, either increase DB_MAX_CONNECTIONS (only if PostgreSQL's max_connections allows it) or reduce GUNICORN_WORKERS.

PgBouncer

When using PgBouncer in transaction mode, set POSTGRES_USE_PGBOUNCER=true. This disables asyncpg's prepared-statement cache, which is incompatible with transaction-mode pooling.

For production, use a managed service instead of in-cluster Postgres:

  • AWS RDS for PostgreSQL
  • Google Cloud SQL
  • Azure Database for PostgreSQL
  • DigitalOcean Managed Databases
  • Supabase

Just set POSTGRES_URI (and optionally POSTGRES_READ_URI) to the connection strings from your managed service.


Redis

Variable Default Description
REDIS_URL redis://redis-service:6379 Redis connection URL
REDIS_MAX_CONNECTIONS 100 Per-process Redis connection pool size
REDIS_RETRY_ATTEMPTS 3 Retry attempts on transient errors
REDIS_RETRY_DELAY 0.1 Delay in seconds between retries
REDIS_CONNECTION_TIMEOUT 10 Connection timeout in seconds
REDIS_ENABLE_CIRCUIT_BREAKER true Open circuit on repeated Redis failures

Rust binary connection pool

The mediafusion-api / mediafusion-worker binaries manage their own SQLx connection pool, separate from the Python workers.

Variable Default Description
DB_POOL_SIZE 10 Max connections for the read-write pool
DB_POOL_SIZE_RO DB_POOL_SIZE Max connections for the read-only replica pool. Defaults to DB_POOL_SIZE when unset. Set this to size the two pools independently (the DB sees DB_POOL_SIZE + DB_POOL_SIZE_RO total from this process).
DB_POOL_MIN 2 Minimum idle connections to keep warm
DB_ACQUIRE_TIMEOUT_SECS 5 Seconds to wait for a free connection before returning an error
DB_IDLE_TIMEOUT_SECS 600 Drop connections idle longer than this many seconds
DB_MAX_LIFETIME_SECS 1800 Recycle connections older than this many seconds — ensures DNS / endpoint re-resolution after a failover
DB_STATEMENT_TIMEOUT_MS 60000 Per-session statement_timeout in milliseconds. Applied on every new connection via SET statement_timeout. Matches the DB-side guard recommended for production.
DB_IDLE_TX_TIMEOUT_MS 60000 Per-session idle_in_transaction_session_timeout in milliseconds. Bounds any accidentally leaked transaction so a stalled request cannot hold row locks indefinitely.

Pool sizing guidance: With a default pool of 10 RW + 10 RO, a single mediafusion-api process uses up to 20 connections. Multiply by your replica count when planning Postgres max_connections. DB_POOL_SIZE=2040 is typical for production; always leave headroom above the total for admin connections and pg_stat_activity queries.


Redis URL for the Rust components

Variable Default Description
REDIS_RS_URL None Separate Redis URL for the Rust binary. Falls back to REDIS_URL if not set.

Performance workers

Variable Default Description
GUNICORN_WORKERS 3 Number of Uvicorn worker processes
GUNICORN_TIMEOUT 120 Request timeout in seconds
GUNICORN_MAX_REQUESTS 5000 Restart a worker after this many requests (prevents memory leaks)
GUNICORN_MAX_REQUESTS_JITTER 2000 Random jitter on top of MAX_REQUESTS
TASKIQ_SINGLE_WORKER_MODE true Route all task queues into one worker process

Set TASKIQ_SINGLE_WORKER_MODE=false for HA deployments where you run dedicated worker processes per queue (default, scrapy, import, priority).