Database and Redis
PostgreSQL
Section titled “PostgreSQL”PostgreSQL is the primary persistent store for SyncTV. User accounts, rooms, playlists, media metadata, audit data, provider credentials, and most durable application state live in PostgreSQL.
Production deployments should treat PostgreSQL as mandatory infrastructure. Back it up before upgrades, test migrations outside production first, and avoid using ephemeral storage for the database.
database.url
Section titled “database.url”Default:
database: url: "postgresql://synctv:synctv@localhost:5432/synctv"For production, prefer a secret file:
database: url_file: "/run/secrets/database_url"Environment variables:
SYNCTV_DATABASE_URL=postgresql://synctv:password@postgres:5432/synctvSYNCTV_DATABASE_URL_FILE=/run/secrets/database_urlSplit Database Configuration
Section titled “Split Database Configuration”Instead of a full URL, you can use split fields:
database: host: "postgres.example.com" port: 5432 username: "synctv" password_file: "/run/secrets/database_password" name: "synctv"If split fields are used without database.url, SyncTV clears the default URL and builds the connection from the split fields. user is accepted as a YAML alias for username; SYNCTV_DATABASE_USER is accepted as an environment alias for SYNCTV_DATABASE_USERNAME.
Connection Pool
Section titled “Connection Pool”| Field | Default | Purpose |
|---|---|---|
database.max_connections | 20 | Maximum PostgreSQL pool size |
database.min_connections | 5 | Minimum idle connections |
database.connect_timeout_seconds | 10 | Timeout while opening a new connection |
database.idle_timeout_seconds | 600 | How long idle connections may stay open |
database.max_lifetime_seconds | 1800 | Maximum lifetime before a connection is recycled |
For small single-node deployments, defaults are usually enough. Increase max_connections only after checking PostgreSQL capacity and other application pools that share the same database.
Redis Role
Section titled “Redis Role”Redis is optional in simple single-node mode but strongly recommended for production. It is required for cluster mode.
Redis backs or improves:
- Token blacklist and revocation sharing.
- Rate limit counters.
- Brute-force protection state.
- Username, permission, and small business caches.
- OAuth2 state storage.
- WebAuthn/passkey challenge storage.
- MFA session storage.
- Cache invalidation.
- Cluster pub/sub, node discovery, health state, and stream catch-up.
If Redis is absent in standalone mode, SyncTV uses in-memory fallbacks where possible. Those fallbacks are lost on restart and cannot be shared across replicas.
redis.url
Section titled “redis.url”Single Redis instance:
redis: url_file: "/run/secrets/redis_url" key_prefix: "synctv:"Environment variables:
SYNCTV_REDIS_URL=redis://redis:6379SYNCTV_REDIS_URL_FILE=/run/secrets/redis_urlSplit Redis Configuration
Section titled “Split Redis Configuration”redis: host: "redis.example.com" port: 6379 username: "" password_file: "/run/secrets/redis_password" database: 0user is accepted as a YAML alias for username; SYNCTV_REDIS_USER is accepted as an environment alias for SYNCTV_REDIS_USERNAME.
Redis Sentinel
Section titled “Redis Sentinel”Sentinel mode connects to a Redis Sentinel deployment. After repeated health-check failures, SyncTV queries Sentinel for the current master and performs a best-effort Redis connection rebuild and hot-swap.
This is not a strict failover guarantee: in-flight Redis operations can still fail during the failover window, and cluster coordination that relies on Redis locks and pub/sub can still be unsafe. For that reason, Sentinel mode cannot be used with cluster.enabled=true.
redis: deployment_mode: "sentinel" sentinel_master_name: "mymaster" sentinel_addresses: - "redis://sentinel-0.redis:26379" - "redis://sentinel-1.redis:26379" - "redis://sentinel-2.redis:26379"For clustered SyncTV, prefer a stable single Redis endpoint, a managed Redis service, or a platform that provides stable connection semantics.
Cluster Dependency
Section titled “Cluster Dependency”When cluster.enabled=true, Redis must be configured. Cluster mode also requires server.cluster_secret.
cluster: enabled: true
server: cluster_secret_file: "/run/secrets/cluster_secret"
redis: url_file: "/run/secrets/redis_url"Without Redis, multi-replica coordination cannot safely provide node registry, pub/sub, health monitoring, catch-up, and distributed leader election behavior.
Operational Notes
Section titled “Operational Notes”- PostgreSQL must be backed up before upgrades and migrations.
- Redis is usually short-lived shared state, but losing it can invalidate OAuth2 state, rate-limit counters, token blacklist data, and cluster coordination state.
- Use a stable
redis.key_prefixwhen sharing a Redis instance with other systems. - Do not expose PostgreSQL or Redis directly to the public internet.