Deployment topology
Radioso is deployed as separate services with a shared PostgreSQL database and explicit separation between request-driven application traffic, background document work, and optional long-lived dashboard streams.
Main components
- Backend API service: handles authenticated app traffic, workspace APIs, retrieval, chat, auth flows, and enqueueing document jobs.
- Frontend app service: serves the product UI and proxies user-facing app traffic to the backend.
- Document worker service: processes queued document jobs outside the request path.
- Realtime service: when enabled, authenticates and serves workspace-scoped dashboard event streams outside the frontend request pool.
- PostgreSQL: stores application state, document metadata, chunks, sessions, settings, and audit data.
- Redis or Valkey: when realtime is enabled, carries transient invalidation hints and short-lived admission leases. PostgreSQL remains authoritative.
- Object storage: uploaded source files use local filesystem storage in local development and GCS in cloud deployments.
Why the worker is separate
Document parsing, chunking, embedding, and retry behavior are operationally different from chat requests. The worker service keeps those concerns isolated so chat does not inherit background-job latency and failure behavior.
Production shape
The base Terraform deployment uses separate Cloud Run services for backend, frontend, and worker. The backend connects to Cloud SQL through a VPC connector. Uploaded source files are stored in GCS, and request-driven document jobs are dispatched to the worker through Cloud Tasks.
A deployment with live dashboard updates adds a dedicated realtime runtime and Redis or Valkey. The frontend keeps the browser connection same-origin at /backend/api/v1/events and forwards that exact route to the realtime service’s internal /api/v1/events endpoint. This keeps long-lived streams out of the ordinary frontend and backend request pools.
Docs portal placement
The docs portal should stay outside the product frontend runtime. It has its own Next.js app, its own build, and its own API-reference sync step. Treat it as a separate public service, not a route mounted inside the customer product app.
In local development, ./run-dev.sh starts the app stack together with Docker Compose. In production, the same logical components stay split so scaling and failures remain easier to reason about.
Operational consequences
- backend scale settings and worker scale settings should be tuned independently
- realtime connection capacity should be tuned independently from ordinary HTTP concurrency
- a document-processing incident should not require frontend changes
- a realtime or Redis incident falls back to polling instead of changing mutation correctness
- public docs deployment should not be coupled to the app frontend release
- storage, secrets, and queue configuration belong to infrastructure, not app code