aloof-scooter-47164
05/09/2026, 4:00 PMtall-airline-16756
05/09/2026, 4:01 PMtall-airline-16756
05/09/2026, 4:01 PMload_threshold = 0.7. Also set a longer terminationGracePeriodSeconds (10+ minutes) to allow sessions to drain.
Sources: Self-hosted deployments | LiveKit Documentation | Voice Agent Architecture: STT, LLM, and TTS Pipelines Explained | LiveKit, with interactive elementsaloof-scooter-47164
05/09/2026, 4:07 PMtall-airline-16756
05/09/2026, 4:07 PMload_threshold=0.7 with 5 min grade period.
Recommendations
• Baseline pod sizing
◦ Keep pods at 4 CPU / 8 GiB as the starting unit. This matches LiveKit guidance and real-world tests for voice agents and gives room for headroom and autoscaling responsiveness.
◦ On your 8 vCPU / 16 GiB nodes, run 2 pods per node (each with 4 CPU) rather than one pod using the whole node. This reduces single-point contention and improves bin-packing for short-lived sessions.
• Expected capacity per pod
◦ Estimate ~10–25 concurrent short sessions per 4 CPU pod. Because your sessions are short and S2S with server-side VAD (no heavy noise cancellation), use the higher end of that range for planning — assume ~20 sessions/pod for steady-state capacity.
• Cluster sizing for targets (rounded)
◦ For 100 concurrent sessions → ~5 pods → with 2 pods/node → 3 nodes (ceil).
◦ For 150 concurrent sessions → ~8 pods → 4 nodes.
◦ For 200 concurrent sessions → ~10 pods → 5 nodes.
(These use 20 sessions/pod estimate; if you prefer conservative 10 sessions/pod, double pod/node and node counts.)
• Autoscaling settings
◦ Keep load_threshold=0.7 on agents. Configure HPA to scale on CPU utilization and trigger scale-up earlier: target CPU ~50% (or 0.5) so new pods are ready before agents hit 0.7.
◦ Use a short scale-up stabilization/aggregation window (e.g., 1–2 minutes) and a longer scale-down cooldown (e.g., 5–10 minutes) to avoid rapid thrashing given short session durations.
◦ Consider using Cluster Autoscaler with node provisioning short delay to match HPA speed.
• Worker/availability tuning
◦ Reduce gradePeriod only if you see slow reaction to load changes — with steady 24/7 load and 5-min sessions, your existing 5-minute gradePeriod is reasonable; keep it unless you observe saturation.
◦ Ensure terminationGracePeriodSeconds is >= session max (5–10 minutes) so pods can drain active sessions cleanly.
• Operational checks during your ramp
◦ Monitor per-pod CPU and memory, agent load_fnc value, pod restart rates, and rejection/queue metrics.
◦ Run a quick canary scale to 100, then 150, watch for sustained CPU >70% or increased rejections before proceeding.
◦ If you see CPU saturating earlier than expected, switch to a conservative capacity assumption (10 sessions/pod) and add nodes.
If you’d like, I can:
• Recompute exact node counts using a different sessions-per-pod assumption (10, 15, or 20).
• Suggest HPA config YAML snippets for target CPU and stabilization windows.
Which follow-up would be most helpful?
, with interactive elementsaloof-scooter-47164
05/09/2026, 4:12 PM# Long enough drain to let in-flight calls finish through a deploy.
terminationGracePeriodSeconds: 300
# Outbound-WS workers don't need a preStop sleep.
preStopSleepSeconds: 0
# Pin to the dedicated cloud agent pool (e2-custom-8-16384)
nodeSelector:
workload: livekit-agent-cloud
tolerations:
- key: "dedicated"
operator: "Equal"
value: "livekit-agent-cloud"
effect: "NoSchedule"
# QoS shape for an async I/O-bound voice workload on e2-custom-8-16384:
# - CPU: requests only, no limits (CFS throttling causes audio jitter).
# - Memory: request == limit (Guaranteed QoS, last to be evicted).
# One pod per node — leaves headroom for kube-system + brief bursts.
resources:
requests:
cpu: "7000m"
memory: "12Gi"
limits:
memory: "12Gi"
readinessProbe:
enabled: true
# maxUnavailable: 1 (instead of minAvailable: N) is self-adjusting as
# minReplicas grows: always exactly one pod can be drained at a time, no
# matter the scale. Avoids the trap where minAvailable: 1 lets all-but-one
# drain in parallel once you have many replicas.
podDisruptionBudget:
enabled: true
maxUnavailable: 1
autoscaling:
enabled: true
# Two warm pods for HA. Bump as you migrate more users to LiveKit Cloud.
# PDB (maxUnavailable: 1) needs minReplicas >= 2 to allow node drains.
minReplicas: 2
# Effectively uncapped. Real ceiling is the cluster's node-pool max + GCP quotas.
maxReplicas: 1000
# Below the agent server's load_threshold (0.7). Lower as a hedge while CPU
# is the only signal — for I/O-bound Realtime workloads, CPU underestimates
# true load.
targetCPUUtilizationPercentage: 50
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 600
policies:
- type: Pods
value: 1
periodSeconds: 60tall-airline-16756
05/09/2026, 4:13 PMload_threshold = 0.7.
◦ Keep HPA target CPU ~50% (good). This gives headroom before agents mark themselves overloaded.
◦ Use short scale-up stabilization window: 60–120s.
◦ Use longer scale-down stabilization/cooldown: 300–600s to avoid thrash given 5-min sessions.
◦ Ensure HPA metrics reflect node-level allocatable vs pod requests so new pods can schedule.
• PodDisruption and draining
◦ Keep terminationGracePeriodSeconds >= session length (300s is okay for ~5 min sessions). If sessions occasionally exceed 5 min, increase to 600s.
◦ PDB maxUnavailable: 1 is good for rolling updates. Ensure minReplicas >= 2 for PDB safety.
• Capacity planning (using ~20 sessions / 4 CPU pod estimate)
◦ 100 sessions → ~5 pods → with 2 pods/node → 3 nodes.
◦ 150 sessions → ~8 pods → 4 nodes.
◦ 200 sessions → ~10 pods → 5 nodes.
◦ If you prefer conservative sizing (10 sessions/pod), double pods & nodes. Validate with canary load tests.
• Short-lived sessions & HPA interplay
◦ Because sessions are ~5 min and spawn immediately, prefer quicker scale-up and slightly delayed scale-down so pods are available for the next sessions.
◦ Consider maintaining a small buffer of warm pods (minReplicas >= 2–3) above steady-state if you see frequent cold starts.
• Operational checks to run during ramp
◦ Track per-pod CPU, memory, agent load_fnc, agent rejection/queue metrics, pod start time, and scheduling latency.
◦ Watch for CPU near 70% before autoscale triggers — if that happens prematurely, drop sessions/pod estimate or increase pods.
◦ Monitor kube-scheduler pending pods to ensure cluster autoscaler is bringing nodes fast enough.
If you want, I can:
• Produce a revised manifest snippet with requests/limits, HPA stabilization windows, and PDB adjustments for 2 pods/node.
• Recalculate nodes/pods using a conservative 10 sessions/pod assumption.
Which follow-up would be most useful?
, with interactive elementsaloof-scooter-47164
05/09/2026, 4:14 PMtall-airline-16756
05/09/2026, 4:14 PMterminationGracePeriodSeconds, preStopSleepSeconds, minReplicas, maxReplicas, targetCPUUtilizationPercentage, and gradePeriod) so I can review exact values and give precise recommendations.
, with interactive elementsaloof-scooter-47164
05/09/2026, 4:15 PM# Long enough drain to let in-flight calls finish through a deploy.
terminationGracePeriodSeconds: 300
# Outbound-WS workers don't need a preStop sleep.
preStopSleepSeconds: 0
# Pin to the dedicated cloud agent pool (e2-custom-8-16384)
nodeSelector:
workload: livekit-agent-cloud
tolerations:
- key: "dedicated"
operator: "Equal"
value: "livekit-agent-cloud"
effect: "NoSchedule"
# QoS shape for an async I/O-bound voice workload on e2-custom-8-16384:
# - CPU: requests only, no limits (CFS throttling causes audio jitter).
# - Memory: request == limit (Guaranteed QoS, last to be evicted).
# One pod per node — leaves headroom for kube-system + brief bursts.
resources:
requests:
cpu: "7000m"
memory: "12Gi"
limits:
memory: "12Gi"
readinessProbe:
enabled: true
# maxUnavailable: 1 (instead of minAvailable: N) is self-adjusting as
# minReplicas grows: always exactly one pod can be drained at a time, no
# matter the scale. Avoids the trap where minAvailable: 1 lets all-but-one
# drain in parallel once you have many replicas.
podDisruptionBudget:
enabled: true
maxUnavailable: 1
autoscaling:
enabled: true
# Two warm pods for HA. Bump as you migrate more users to LiveKit Cloud.
# PDB (maxUnavailable: 1) needs minReplicas >= 2 to allow node drains.
minReplicas: 2
# Effectively uncapped. Real ceiling is the cluster's node-pool max + GCP quotas.
maxReplicas: 1000
# Below the agent server's load_threshold (0.7). Lower as a hedge while CPU
# is the only signal — for I/O-bound Realtime workloads, CPU underestimates
# true load.
targetCPUUtilizationPercentage: 50
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 600
policies:
- type: Pods
value: 1
periodSeconds: 60tall-airline-16756
05/09/2026, 4:15 PMaloof-scooter-47164
05/09/2026, 4:18 PMtall-airline-16756
05/09/2026, 4:18 PMcpu: "4000m", memory: "8Gi" only if your node allocatable >= 8 CPU and >=16 GiB. Because allocatable is lower, confirm allocatable before applying.
b. Query actual allocatable on a node:
• Run kubectl get node <node-name> -o jsonpath='{.status.allocatable}' (or kubectl describe node <node-name>).
• Check current DaemonSet usage with kubectl top node and kubectl get pods -n kube-system -o wide.
a. If allocatable is lower than needed for two 4 CPU/8 Gi pods:
• Option A: reduce pod requests slightly (e.g., 3900m CPU / 7.5Gi) only after validating LiveKit performance under load.
• Option B: keep pod requests at 4 CPU / 8 Gi and run 1 pod/node (conservative, simpler).
• Option C: add a small node-level buffer by setting requests to 3.5–3.8 CPU if tests show capacity per pod remains acceptable.
a. Confirm Cluster Autoscaler and HPA consider allocatable resources so new pods can schedule.
• Recommended immediate checks:
◦ Run kubectl describe node to see Allocatable CPU/Memory.
◦ Check kubelet flags or cluster config for kube-reserved and system-reserved values.
◦ Inspect DaemonSets using node resources (fluentd/metrics).
If you paste the output of kubectl describe node <one-of-your-nodes> (Allocatable section) I’ll recompute whether 2x 4CPU/8Gi pods per node is safe or suggest exact pod requests to fit your real allocatable capacity.
, with interactive elementsaloof-scooter-47164
05/09/2026, 4:22 PMtall-airline-16756
05/09/2026, 4:22 PM