API and realtime
HTTP REST, public gRPC, WebSocket, and room realtime events share the same business services and permission model.
SyncTV is a single-binary service. One process contains HTTP APIs, public gRPC, WebSocket realtime rooms, management gRPC, media providers, proxying, livestreaming, and cluster coordination.
Start with the single-node production model: clients reach SyncTV through a TLS reverse proxy or Ingress, SyncTV connects to PostgreSQL, and Redis is recommended for shared short-lived state.
PostgreSQL is durable business state. Redis is shared short-lived state and coordination. data_dir is the local runtime file directory. When you need horizontal scaling, add multiple SyncTV replicas, shared PostgreSQL/Redis, a unified edge entrypoint, and an explicit HLS storage or publisher-node proxy model.
| Level | Use case | Required components | Extra attention |
|---|---|---|---|
| Single-node production | Small team or one server | SyncTV, PostgreSQL, production secrets | Redis is recommended, backups are required |
| Temporary local evaluation | UI preview or development preflight | SyncTV, PostgreSQL | Development Compose secrets are acceptable only locally; do not use publicly or long term |
| Multi-replica production | Horizontal scaling, rolling updates, highly available entrypoints | Multiple SyncTV instances, PostgreSQL, Redis, cluster secret | Split HTTP/gRPC Ingresses and choose an HLS model |
API and realtime
HTTP REST, public gRPC, WebSocket, and room realtime events share the same business services and permission model.
Authentication
Password, OPAQUE, passkey/WebAuthn, email codes, OAuth2, user-level 2FA, and JWT tokens make up the login layer.
Media
Providers resolve external media, the proxy performs controlled forwarding, and slice cache stores Range slices only.
Horizontal scaling
Multi-node deployments use Redis, discovery, leader election, and transactional outbox delivery boundaries.
| Surface | Default port or path | Purpose | Production guidance |
|---|---|---|---|
| HTTP REST | server.port=8080 | Client API, health checks, OpenAPI UI | Expose through a reverse proxy or Ingress |
| Public gRPC | server.port=8080 | gRPC API for clients or SDKs | Use a separate Kubernetes Service and Ingress |
| WebSocket | server.port=8080 | Room realtime events, playback sync, chat | Configure connection limits and shutdown drain |
| Management gRPC | Unix socket or management.port=50052 | CLI, administration, operational control plane | Prefer Unix socket; TCP requires a token |
| Metrics | metrics.port=9090 | Prometheus metrics | Keep private and authenticated |
| RTMP | livestream.rtmp_port=1935 | Livestream publishing | Expose only when livestreaming is used |
| STUN UDP | webrtc.stun_port=3478 | WebRTC NAT assistance | Expose only when built-in STUN is used |
HTTP REST and public gRPC share the main process port, but Kubernetes deployments should still use separate Services and Ingresses. This lets the gRPC Ingress set nginx.ingress.kubernetes.io/backend-protocol: "GRPC" independently.
PostgreSQL is the durable system of record. Users, rooms, permissions, provider instances, user preferences, audit data, and business records live there.
Production requirements: startup runs embedded SQLx migrations automatically; maintain backup and restore procedures; keep connection pool sizing within database capacity; treat database migrations as rollback-sensitive.
Redis stores shared short-lived state and distributed coordination data. Single-node deployments can run without Redis, but production and multi-replica deployments should configure it.
Redis affects rate limits, brute-force protection, token blacklist, OAuth2 state, WebAuthn challenges, email verification state, L2 cache, cluster node registry, and event catch-up.
Redis is usually not a long-term backup target, but restarting or clearing it affects in-flight authentication, rate windows, and cluster short-term state.
data_dir is the root directory for runtime-owned local files.
Common contents include the management Unix socket, file logs, HLS files, and file-backed proxy slice cache.
Static input files such as *_file secrets and TLS certificates are not rebased under data_dir.
User-Agent, Referer, Range, or authentication headers.Cluster mode is for multi-replica deployments. When cluster.enabled=true, Redis and cluster.secret are required.
Key settings:
| Setting | Purpose |
|---|---|
cluster.discovery_mode | Node discovery: redis, static, or k8s_dns |
cluster.leader_election_mode | Background task leader election: redis or k8s_lease |
server.advertise_host | Address other nodes use to reach this node |
cluster.secret | Authentication for inter-node gRPC calls |
cluster.catchup_window_secs | Event replay window after short disconnects |
For multi-replica deployments, also confirm:
redis.key_prefix.shared_file serves TS segments from the current node’s shared mount, and OSS provides object-storage-backed segment storage.server.shutdown_drain_timeout_seconds.For the full runtime design, discovery modes, leader election, and clustered livestreaming boundaries, see Cluster Configuration.
The livestream path is separate from the on-demand proxy path. RTMP is the publishing entrypoint; HTTP-FLV serves low-latency playback; HLS remuxing produces playlists and segments into the selected memory, file, or oss backend. In multi-replica deployments, the publisher owner is exposed through a shared registry; today non-publisher nodes read playlists and segments through the HLS gRPC proxy to the publisher node. Shared filesystem storage or OSS is a storage and recovery boundary, not a signal that non-publisher nodes bypass the publisher and read segments directly.
For the RTMP/StreamHub/HTTP-FLV/HLS pipeline, backend selection, and clustered livestreaming failure boundaries, see Livestream Configuration.
Kubernetes multi-replica topology: