By Sagar Shankaran, Founder of CallSphere
How to scale a voice AI platform to 100+ concurrent calls. K8s HPA, OpenAI Realtime pooling, Twilio media streams. CallSphere vs Vapi capacity tradeoffs.
Key takeaways
Scaling voice AI past 50 concurrent calls is where most stacks break. Vapi abstracts scaling behind a managed plane; you pay per minute and trust the vendor's pool — which usually works, occasionally spikes during platform-wide load. CallSphere runs on k3s with horizontal pod autoscaling, OpenAI Realtime connection pools, and Twilio Media Streams with sticky session routing per call. The Sales platform ships with 5 concurrent outbound by default; the broader platform tunes per vertical to 100+ inbound concurrent on commodity hardware.
This post is the SRE-grade walk-through: what breaks, where to put autoscalers, and which knobs are load-bearing.
A single concurrent voice call burns:
Multiply by 100 and you have:
This is not a heavy workload. The hard part is connection lifecycle correctness under churn.
Vapi runs a multi-tenant managed plane. From a customer's perspective:
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
Strengths: zero ops; small teams hit this and forget it.
Weaknesses: opaque caps, no surge planning, geographic pinning is vendor-side, capacity contention with other tenants during their surges.
CallSphere is a single-tenant or VPC-deployable platform on k3s. The capacity stack is:
Twilio Media Streams ── load balancer ──┐
▼
┌──────────────────────┐
│ Voice Agent Pods │
│ (FastAPI per pod) │
│ HPA min=2 max=20 │
└──────────────────────┘
│
OpenAI Realtime WS pool (per-pod)
│
Postgres (Prisma) + Redis (state cache)
Each pod is sized for 30-50 concurrent calls. With max=20 replicas, the platform handles 600-1000 concurrent. With cluster autoscaling on top, it scales further but the practical sweet spot is 100-200 concurrent per single-cluster deployment.
The naive CPU-based HPA does not work for voice — calls are I/O bound, CPU stays low. CallSphere uses a custom metric: active_calls_per_pod.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: voice-agent
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: voice-agent
minReplicas: 2
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: active_calls_per_pod
target:
type: AverageValue
averageValue: "30"
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Percent
value: 50
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
Three knobs do all the work:
Each pod runs an asyncio task that maintains a pool of OpenAI Realtime WebSockets. When a call arrives:
class RealtimePool:
def __init__(self, size: int = 8):
self.pool: asyncio.Queue = asyncio.Queue(maxsize=size)
self.target_size = size
async def acquire(self) -> RealtimeSession:
try:
return await asyncio.wait_for(self.pool.get(), timeout=0.05)
except asyncio.TimeoutError:
return await self._create_session()
async def release(self, session: RealtimeSession):
if self.pool.qsize() < self.target_size and session.healthy:
await session.reset()
await self.pool.put(session)
else:
await session.close()
The 50ms acquire timeout is intentional — if the pool is exhausted, create rather than queue, and trust HPA to add capacity.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
For outbound campaigns (Sales platform), CallSphere caps 5 concurrent by default per campaign. Reason: outbound dial pacing matters for STIR/SHAKEN reputation, and downstream carriers throttle aggressive dialers. The cap is per-campaign, so two simultaneous campaigns with 5 each = 10 total concurrent outbound.
For inbound, no cap — let HPA do its job.
| Dimension | Vapi | CallSphere |
|---|---|---|
| Default concurrency cap | ~50 (Team) | None on inbound; 5/campaign outbound |
| Scaling approach | Vendor-managed pool | K8s HPA on active_calls_per_pod |
| Visibility | Dashboard | Prometheus + Grafana, full metrics |
| Multi-tenant noise | Yes | Single-tenant or VPC option |
| Surge pre-scale | Not exposed | Predictive HPA + manual override |
| Geographic redundancy | Vendor regions | Per-cluster, you choose regions |
| Cost at 100 concurrent | $0.30-0.33/min × usage | Compute + per-minute LLM + Twilio |
| Failure isolation | Tenant blast radius | Pod-level isolation |
graph TB
Caller1[Caller 1] --> Twilio
Caller2[Caller 2] --> Twilio
CallerN[Caller N] --> Twilio
Twilio[Twilio Media Streams] --> LB[Ingress LB]
LB --> Pod1[Voice Pod 1<br/>30 calls]
LB --> Pod2[Voice Pod 2<br/>28 calls]
LB --> Pod3[Voice Pod 3<br/>32 calls]
Pod1 --> Pool1[Realtime WS Pool]
Pod2 --> Pool2[Realtime WS Pool]
Pod3 --> Pool3[Realtime WS Pool]
Pool1 --> OpenAI[OpenAI Realtime API]
Pool2 --> OpenAI
Pool3 --> OpenAI
HPA[HPA Controller] -.->|active_calls_per_pod| Pod1
HPA -.-> Pod2
HPA -.-> Pod3
Metrics[Prometheus] -->|scrape| Pod1
Metrics --> Pod2
Metrics --> Pod3
Metrics --> HPA
Pod1 --> Redis[(Redis state)]
Pod2 --> Redis
Pod3 --> Redis
Pod1 --> PG[(Postgres)]
Pod2 --> PG
Pod3 --> PG
~50 concurrent calls on a 4-vCPU pod. We tested to 80 but quality of voice activity detection degrades above 60.
Outbound queue with token-bucket rate limiter at 30 calls/sec, plenty of headroom.
At the cluster level, yes — large customers get their own k3s namespace. Within a namespace, pods are pooled across tenants of the same vertical.
30-50 MB steady, ~100 MB during a tool-heavy multi-handoff turn.
Yes — overflow campaigns get queued in Redis and replay when capacity opens. Inbound never queues; if all pods are at cap, we add more pods within ~30s.
The /features page documents per-vertical concurrency defaults, and the /demo interactive flow shows pod-level metrics live during a multi-call test session.

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
Tbilisi professional-services firms serving relocating founders and IT companies use CallSphere AI voice and chat agents to answer enquiries 24/7 in English, Georgian and Russian and book consultations.
A how-to for Colombian education and tutoring SMBs to answer parents and students instantly, book trial classes 24/7 in Spanish and English, and grow enrollment with a CallSphere AI agent.
Ethiopian coffee exporters and cooperatives lose buyer enquiries across time zones. See how a CallSphere AI voice and chat agent answers international coffee buyers 24/7 in Amharic and English.
A practical how-to for Palau eco-resorts and dive operators on capturing every high-value, multilingual enquiry with a CallSphere AI voice and chat agent, while honouring Palau’s marine-conservation commitments.
How salons, spas and wellness SMBs across the UAE, Saudi Arabia and Qatar use CallSphere AI voice and chat agents to capture every booking 24/7 in Arabic, English and expat languages, and cut no-shows.
How estate agents and property managers in Luxembourg City and across the Grand Duchy use CallSphere to capture multilingual viewing and enquiry calls 24/7, GDPR compliant.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.
Try Live DemoBook a DemoCalculate Your ROI