# VARTA Voice Agent Platform — Technology Stack & Deployment Requirements

VARTA ships as four Docker services — a FastAPI API running the L1–L7 workflow engine, a LiveKit SIP voice worker, a React designer studio, and PostgreSQL — deployable with Compose or Kubernetes in your own environment.

*Prepared for client evaluation — 2026-07-21*

---

## 1. Platform Overview

VARTA is a SaaS voice-agent platform that runs automated, multilingual phone
conversations over SIP telephony. It consists of four deployable services, all
shipped as Docker containers:

| Service | Role |
| --- | --- |
| API (api) | FastAPI backend — workflow engine (L1–L7 conversation layers), session runtime, TTS cache builder, analytics, REST/WebSocket APIs |
| Voice Worker (worker) | LiveKit Agents SIP worker — answers/places phone calls, streams audio, runs STT/VAD/TTS per call |
| Web (web) | React designer & operations studio — workflow builder, call history, live call panel, analytics dashboards |
| Database (db) | PostgreSQL — workflows, sessions, per-turn traces, cost ledger |

## 2. Technology Stack

### Backend

| Component | Technology | Version |
| --- | --- | --- |
| Language / runtime | Python | 3.12 (python:3.12-slim Debian image) |
| Web framework | FastAPI | 0.116 |
| ASGI server | Uvicorn (with uvloop/httptools) | 0.35 |
| ORM / migrations | SQLAlchemy 2.0 + Alembic | 2.0.43 / 1.16 |
| Validation / config | Pydantic v2 + pydantic-settings | 2.11 |
| HTTP client | httpx (async) + requests | 0.28 |
| JSON serialization | orjson | 3.11 |
| Voice agent framework | LiveKit Agents + provider plugins | 1.3.5 |
| Voice activity detection | Silero VAD (via livekit-plugins-silero, on-CPU) | 1.3.5 |
| Date/time NLU | dateparser | 1.2 |
| Credential encryption | cryptography (Fernet, at-rest encryption of integration credentials) | ≥42 |
| PDF reports | WeasyPrint | latest |

### Frontend

| Component | Technology | Version |
| --- | --- | --- |
| Framework | React | 18.3 |
| Build tool | Vite | 6.x (Node 20) |
| Workflow canvas | @xyflow/react (React Flow) + dagre auto-layout | 12.x |
| State management | Zustand | 5.x |
| Charts / analytics | Recharts | 2.15 |
| Browser calling | livekit-client (WebRTC) | 2.18 |
| Testing | Vitest + Testing Library | 2.x |

Production build is a static bundle (HTML/JS/CSS) — servable by Nginx, a CDN,
or any static file host behind HTTPS.

### Databases & Storage

| Store | Technology | Purpose |
| --- | --- | --- |
| Primary database | PostgreSQL 15+ (15-alpine in prod compose, 18 supported) | Workflows, sessions, call transcripts, per-turn layer traces, cost ledger, campaign data |
| Dev fallback | SQLite | Local development only |
| Audio cache | Local filesystem volume (/data/audio) | Pre-synthesized TTS clips (survives redeploys; shared between API and voice worker) |
| Key-value store | File-backed JSON store (Redis-swappable interface) | Counters and runtime state; designed to move to Redis for horizontal scale |

### Logging & Observability

- **Structured application logging** — Python `logging` with per-component
loggers (`tts_builder.*`), stdout/JSON → collectable by Docker log drivers
(ELK, Loki, CloudWatch, etc.).
- **OpenTelemetry** — full OTel SDK with OTLP exporters (gRPC + HTTP) built
in; traces/metrics can be pointed at any OTLP collector (Grafana Tempo,
Jaeger, Datadog, New Relic).
- **Per-call conversation traces** — every turn records which engine layer
(L1–L7) answered, latency breakdown (STT/LLM/TTS/silence), and token/char
usage, viewable in the web UI's Call History tab.
- **Per-call cost ledger** — metered STT seconds, LLM tokens, and TTS
characters per call and per turn, with analytics dashboards (cost per
workflow, savings estimates).

### Third-Party Services (HTTPS APIs)

All external integrations are over outbound HTTPS/WSS; keys are configured per
deployment, and LLM/TTS/STT providers are selectable **per workflow**.

| Category | Providers supported | Notes |
| --- | --- | --- |
| LLM | OpenAI (default), Google Gemini | Provider-agnostic factory; per-workflow model selection (gpt-4o/4.1/5.x, gemini-2.5/3.x families) |
| TTS | ElevenLabs (full multilingual set), Sarvam AI Bulbul (Indian languages) | Heavy TTS caching — repeated prompts are synthesized once and replayed from disk |
| STT | Deepgram (incl. keyterm phrase biasing), ElevenLabs Scribe | Per-workflow provider field + per-call override; Sarvam STT integration planned |
| Embeddings / moderation | OpenAI | Used by the intent classifier |
| Media / telephony infra | LiveKit (Cloud or self-hosted) | WebRTC media server + SIP gateway |

### SIP Telephony Integration

- Built on **LiveKit SIP**: calls arrive/depart via a SIP trunk connected to
LiveKit's SIP gateway; the voice worker joins the call's media room and runs
STT → conversation engine → TTS in real time.
- **Trunk-agnostic** — works with any standards-compliant SIP trunk provider
(Twilio, Telnyx, Plivo, Exotel, or a carrier-direct trunk). Phone numbers
(DIDs) are provisioned at the trunk provider and mapped to workflows.
- Inbound and outbound (campaign dialing) supported; barge-in, VAD-based
turn detection, echo-margin tuning, and live call-status tracking included.
- Concurrency model: **process-per-call** (LiveKit Agents
`JobExecutorType.PROCESS`) — each concurrent call is an isolated OS process,
giving fault isolation (one bad call cannot crash others) and linear,
predictable horizontal scaling.

## 3. Supported Operating Systems

Everything ships as Linux containers, so the only hard host requirement is a
container runtime:

| Environment | Support |
| --- | --- |
| Linux x86_64 (Ubuntu 22.04/24.04 LTS, Debian 12, RHEL/Rocky 9, Amazon Linux 2023) | Recommended for production — Docker Engine or Kubernetes |
| Kubernetes (EKS / GKE / AKS / on-prem) | Supported — recommended at 1000-call scale for autoscaling the worker fleet |
| Windows 11 / Windows Server | Development & evaluation via Docker Desktop (current dev environment) |
| macOS | Development via Docker Desktop |

Container base images: `python:3.12-slim` (Debian), `node:20-alpine`,
`postgres:15/18-alpine`.

## 4. Sizing — 1,000 Parallel Calls on 100 Telephony Numbers

**Assumptions:** audio-only calls (G.711/Opus ≈ 100 kbps per leg), average
~10 concurrent calls per DID across 100 numbers, STT/LLM/TTS via external
HTTPS providers (no on-prem GPU inference required), LiveKit self-hosted. Each
live call consumes roughly **0.25 vCPU average (0.5 peak)** and **~250–300 MB
RAM** in its worker process (Silero VAD + audio streaming + engine I/O).

### Recommended production fleet (1,000 concurrent calls)

| Tier | Machines | Spec each | Purpose |
| --- | --- | --- | --- |
| Voice workers | 10 | 32 vCPU / 64 GB RAM / 100 GB SSD | ~100 concurrent calls per node (process-per-call); scale linearly, N+1 for headroom |
| LiveKit media (SFU) | 2 | 16 vCPU / 32 GB RAM | Audio-only rooms; HA pair. (Replaceable by LiveKit Cloud — removes this tier entirely) |
| LiveKit SIP gateway | 2 | 8 vCPU / 16 GB RAM | 1,000 concurrent SIP sessions across 100 DIDs; HA pair |
| API backend | 3 | 8 vCPU / 16 GB RAM | FastAPI/Uvicorn, ~200–400 turn-requests/sec at peak, behind a load balancer |
| PostgreSQL | 1 (+1 replica) | 16 vCPU / 64 GB RAM / 500 GB NVMe | Primary + streaming replica; PgBouncer recommended |
| Frontend + LB | 2 | 4 vCPU / 8 GB RAM | Nginx: static React bundle + TLS termination / reverse proxy |

**Totals:** ≈ **430 vCPU / 900 GB RAM** across ~20 nodes.
**Network:** ~250 Mbps sustained audio at peak → 1 Gbps uplinks; low-latency
(<50 ms) path to the SIP trunk provider.
**Storage:** TTS audio cache grows with workflow count (typically 10–50 GB);
call traces/analytics in Postgres (~1–2 MB per call including per-turn traces).

### Minimum single-server configuration (pilot / up to ~50 concurrent calls)

| Resource | Minimum |
| --- | --- |
| Machine | 1 × 16 vCPU / 32 GB RAM / 200 GB SSD |
| OS | Ubuntu 22.04 LTS + Docker Compose (the shipped docker-compose.prod.yml) |
| Network | 100 Mbps, public HTTPS endpoint + SIP trunk connectivity |
| Runs | API + worker + web + Postgres + (optionally) LiveKit, all on one host |

### Scaling notes & real-world bottlenecks

1. **Third-party concurrency limits are usually the binding constraint at
1,000 calls, not hardware** — ElevenLabs concurrent-synthesis slots,
Deepgram concurrent streams, and OpenAI/Gemini tokens-per-minute all need
enterprise-tier quotas. This should be sized with the providers before
go-live.
2. **SIP trunk capacity** — the trunk must be provisioned for 1,000
simultaneous channels (100 DIDs is a numbering question, not a capacity
one; concurrent channels are purchased separately with most carriers).
3. **TTS caching materially cuts cost and latency** — static and templated
prompts are pre-synthesized and served from disk, so at steady state only
dynamic sentences hit the TTS API.
4. **Horizontal scaling** — voice workers are stateless (state lives in the
API + Postgres); add nodes to add capacity. At this scale we recommend
Kubernetes with autoscaling on the worker deployment, Redis substituted
for the file-backed KV store, and LiveKit Cloud if self-hosting the media
layer is not desired.

## 5. Security & Network Summary

- All external traffic over **HTTPS/WSS** (TLS terminated at Nginx/LB);
SIP media via LiveKit (SRTP-capable).
- Third-party credentials held in environment configuration; customer-system
integration credentials encrypted at rest (Fernet/AES).
- Only required inbound ports: 443 (HTTPS), SIP/RTP ranges on the SIP gateway,
LiveKit WebRTC ports. Database and internal services stay on a private
network.
- CORS-restricted API; per-deployment origin allowlist.