rich-megabyte-73517
04/15/2026, 8:58 PMtall-airline-16756
04/15/2026, 8:58 PMtall-airline-16756
04/15/2026, 8:58 PMload_fnc (default: CPU) and stop accepting new jobs when load ≥ load_threshold (default: 0.7). Confirm your workers’ load function and threshold are appropriate so busy workers are marked full and new jobs go to others.
• For self-hosted: autoscale agent workers (e.g., Kubernetes HPA using CPU or custom metrics) so new workers are created before existing ones hit capacity.
• For LiveKit Cloud: the platform will elastically scale agents for you — verify scaling settings and that new instances are coming up when load increases.
• Verify networking/registration issues: if extra tasks are running but still not used, check logs and the LiveKit dashboard to confirm each worker registered successfully and isn’t being marked unhealthy or full immediately.
Quick checklist to run now
1. Confirm you have multiple agent workers running and registered.
2. Check each worker’s health and load metrics (CPU, load_threshold behavior).
3. Inspect logs for registration or network errors on the workers that are not receiving jobs.
4. If self-hosted, add autoscaling rules so new workers start before capacity is reached.
If you want, tell me:
• How you’re deploying agents (LiveKit Cloud or self-hosted/Kubernetes),
• How many worker tasks you currently have running,
• Any worker logs showing registration or “full” events.
I’ll suggest the exact checks and config changes next based on that.
Sources: Self-hosted deployments | LiveKit Documentation | Deploy and scale agents on LiveKit Cloud | LiveKit | Agents Framework | livekit/livekit_composite | DeepWiki | Deployment reliability on LiveKit Cloud | LiveKit, with interactive elementsrich-megabyte-73517
04/15/2026, 9:00 PMtall-airline-16756
04/15/2026, 9:00 PM/stats endpoint (usually http://<livekit-host>:7880/stats) and look for agent/worker entries and their statuses. This shows active agents and basic metrics.
• Server logs
◦ Check the LiveKit server logs for worker registration entries. Look for lines showing agents connecting/registered or any errors about agent registration or health checks.
• Agent logs
◦ On each worker host, check the agent process logs for successful registration messages and for any “marked full” or unhealthy events.
• Prometheus / metrics (if enabled)
◦ If you expose LiveKit metrics, inspect Prometheus for agent-related metrics (registered agents, load, or job assignments) to see how many are active.
• LiveKit dashboard (if you run the UI)
◦ If you have the LiveKit dashboard running, it shows connected agents and their states.
Quick checks to run now
1. Curl the server stats: curl http://<livekit-host>:7880/stats and scan for agent entries.
2. Tail the LiveKit server log while restarting or starting a worker to watch registration messages.
3. On each worker host, journalctl -u <agent-service> or check the agent log file for “registered” confirmations.
If you’d like, tell me:
• the LiveKit server host/port you can access (or paste a redacted /stats output), and
• a sample server or agent log snippet,
and I’ll point to the exact lines to confirm registration and any issues.
, with interactive elementsrich-megabyte-73517
04/15/2026, 9:03 PMtall-airline-16756
04/15/2026, 9:04 PMcurl http://<livekit-host>:7880/stats and look for agent entries and worker counts. Share the redacted output if you want me to read it.
1. Verify each ECS task’s agent processes actually registered
• On each task host, check agent logs for “registered” lines or connection errors.
• For systemd/launcher logs: journalctl -u <agent-service> or view the container logs in ECS for the agent process.
• If one task’s health is “Unknown”, that task may not have completed registration or is failing health checks.
1. Check agent configuration values
• Ensure all workers use the same agent_name if you intend them to be pooled.
• Confirm load_fnc and load_threshold settings (default: CPU & 0.7). If a worker is above threshold it will stop receiving new jobs.
• Make sure each worker has unique process IDs but the same agent name (if you want them to be treated as separate workers under the same agent).
1. Inspect health/metrics and networking
• Confirm ECS task networking allows outbound connection to the LiveKit server (no firewall/NACL blocking).
• Look at LiveKit server logs to see if it marks any agent as unhealthy or rejects registrations.
1. Quick validation test
• Restart one ECS task’s agent while tailing the LiveKit server logs to watch registration events — you should see the worker connect and the server assign jobs to it after it’s healthy.
• After confirming both are registered as healthy, attempt the 8 concurrent calls again.
If you want, paste:
• The /stats output (redact secrets) or
• One agent log snippet from a task showing registration or errors
I’ll point out the exact lines to confirm registration and why the “Unknown” health task isn’t receiving jobs.
, with interactive elementsrich-megabyte-73517
04/15/2026, 9:04 PMtall-airline-16756
04/15/2026, 9:05 PMload_fnc = CPU utilization (values 0–1) and load_threshold default = 0.7. When a worker’s computed load ≥ threshold it stops accepting new jobs.
• Recommended baseline: a 4‑core / 8GB agent can handle ~10–25 concurrent jobs depending on your workload (speech, recordings, codecs, etc.).
If you want a strict per-worker job limit
• Implement a custom load function that returns load = active_jobs / max_jobs (clamped to 1.0). That makes LiveKit treat each worker as able to handle up to max_jobs.
Sizing and autoscaling tips
• Scale before hitting load_threshold (e.g., scale at 0.5 if threshold is 0.7).
• Monitor CPU, memory and active_jobs metrics and increase worker count or instance size if load approaches threshold.
Next step
• Would you like the exact example of a custom load function to enforce N calls per worker, or help interpreting your current /stats output? Sources: Self-hosted deployments | LiveKit Documentation | Server options | LiveKit Documentation | Voice Agent Architecture: STT, LLM, and TTS Pipelines Explained | LiveKit, with interactive elementsrich-megabyte-73517
04/15/2026, 9:12 PM/stats output?
yes, so how do we know how many calls per worker do we assing? what does a worker do? do the stt and other things are shared? what are the best practices?tall-airline-16756
04/15/2026, 9:12 PMload_fnc (CPU utilization) and load_threshold (default 0.7). When computed load ≥ threshold, the worker stops accepting new jobs.
• That means one worker can accept multiple calls until its measured load hits the threshold.
If you want strict “N calls per worker”
• Use a custom load function that reports load = active_jobs / N (capped at 1.0). Example:
def compute_load(server):
return min(len(server.active_jobs) / N, 1.0)
server.load_fnc = compute_load
Or TypeScript:
const computeLoad = (server: AgentServer) => Math.min(server.activeJobs.length / N, 1);
server.loadFnc = computeLoad;
• With this, each worker will accept up to N concurrent jobs before being considered “full.”
Best practices
• Start with the 4 CPU / 8 GB baseline and run load tests reflecting your actual features.
• Scale before threshold: autoscale at a lower point (e.g., 0.5) if threshold = 0.7 to avoid rejections.
• Prewarm heavy models (VAD, STT, LLM) on worker startup to avoid spikes on first session.
• Use observability: monitor CPU, memory, active_jobs, and /stats to tune N and instance sizes.
• Allow graceful drain on deploys (10+ minute grace for voice sessions).
Next step I can help with
• If you want, tell me the instance size and average CPU/memory during calls or paste a redacted /stats output, and I’ll suggest an initial N and either a load_fnc or sizing change to reach it. Sources: Server lifecycle | LiveKit Documentation | Self-hosted deployments | LiveKit Documentation | Voice Agent Architecture: STT, LLM, and TTS Pipelines Explained | LiveKit | Server options | LiveKit Documentation | Deploy and scale agents on LiveKit Cloud | LiveKit, with interactive elementsrich-megabyte-73517
04/15/2026, 9:16 PMtall-airline-16756
04/15/2026, 9:16 PM/stats (or metrics) and check worker CPU and active_jobs. Stop accepting new sessions when load approaches your load_threshold.
3. If you want deterministic limits, use a custom load_fnc that reports load = active_jobs / N to enforce N calls per worker.
4. Autoscale: scale up before the threshold (e.g., scale at 0.5 if threshold = 0.7).
If you want, I can:
• Provide the exact custom load_fnc code (Python/TypeScript) to enforce N calls per worker, or
• Help interpret your /stats output or a short load-test result to pick an appropriate N. Which would you prefer? Sources: Self-hosted deployments | LiveKit Documentation | Voice Agent Architecture: STT, LLM, and TTS Pipelines Explained | LiveKit, with interactive elementsrich-megabyte-73517
04/15/2026, 9:18 PMtall-airline-16756
04/15/2026, 9:18 PMload_fnc and a load_threshold of 0.7 by default.
• Each worker reports a load value (0–1) based on CPU; when load ≥ 0.7 the worker stops accepting new jobs.
• The server will distribute new sessions across registered, healthy workers based on those load signals (so jobs are auto-balanced without custom code).
What you should still do
• Verify your workers register and appear healthy (/stats or server logs).
• Monitor CPU and active_jobs to ensure the default CPU metric reflects your actual capacity.
• If you need a strict per‑worker job limit or your workload isn’t well represented by CPU alone, implement a custom load_fnc (or autoscale) instead.
If you want, I can provide the exact default behavior log lines to look for in /stats or show a short custom load_fnc example to enforce N calls per worker. Which would you like?
, with interactive elementsrich-megabyte-73517
04/15/2026, 9:19 PMtall-airline-16756
04/15/2026, 9:20 PMload_fnc will revert the agent to LiveKit’s default CPU‑based load reporting (with a load_threshold of 0.7). That default behavior works for self‑hosted deployments as long as your agents are correctly registered and healthy.
Safe steps to switch back
1. Remove or disable your custom load_fnc in the agent code/config.
2. Restart the agent processes so they register with the server using the default load function.
3. Verify registration and load reporting:
◦ Curl http://<livekit-host>:7880/stats and confirm agents appear and report a load value.
◦ Check agent and server logs for “registered” and health messages.
1. Monitor CPU and active_jobs for a few load cycles to ensure CPU reflects your true capacity and that sessions are being balanced.
When to keep a custom function
• If CPU doesn’t reflect your real constraint (e.g., you want to limit N concurrent calls per worker), implement a load_fnc that uses active job count or a combined metric.
If you want, I can:
• Show the minimal change to remove your custom load_fnc, or
• Provide a short load_fnc example that enforces N calls per worker. Which do you prefer?, with interactive elementsrich-megabyte-73517
04/15/2026, 9:24 PMtall-airline-16756
04/15/2026, 9:24 PMload_fnc. The on_request (or request handler) can stay — it handles job setup logic, not load reporting.
What to do
1. Remove/disable the custom load_fnc so the agent falls back to LiveKit’s default CPU-based load reporting (threshold 0.7).
2. Keep your on_request handler intact if it performs session setup (prewarm, model init, routing, etc.).
3. Restart the agent so it re-registers with the server using the default load function.
4. Verify with curl http://<livekit-host>:7880/stats and agent/server logs that agents appear healthy and report load values.
If you want, paste your on_request and load_fnc snippets and I’ll show the minimal edit to remove only the load_fnc.
, with interactive elementsrich-megabyte-73517
04/15/2026, 10:30 PMtall-airline-16756
04/15/2026, 10:30 PMon_request / handler) in the AgentServer — do NOT call subprocess.Popen yourself.
3. Use a custom load_fnc only if you need to limit by active job count; otherwise rely on the default CPU-based load function.
4. Prewarm heavy models in startup (setup/prewarm) so subprocesses don’t pay the cold-start cost.
5. Monitor /stats, CPU, memory, and active_jobs to size workers and autoscale.
Minimal example (concept)
server = AgentServer()
@server.rtc_session(agent_name="my-agent")
async def handler(ctx):
# session logic (no manual subprocesses)
...
if __name__ == "__main__":
server.start()
If you currently have 1 task → 2 workers → 4 manually spawned subprocesses, that likely means each worker is creating job subprocesses under load — which is expected. Remove any additional custom subprocess spawning so the SDK controls job lifecycle.
Next step
• If you want, paste your agent start code and any subprocess logic and I’ll show the minimal edits to remove manual subprocesses and run N workers cleanly. Sources: Agents Framework | livekit/livekit_composite | DeepWiki | Server lifecycle | LiveKit Documentation | Job lifecycle | LiveKit Documentation | Server options | LiveKit Documentation | Self-hosted deployments | LiveKit Documentation, with interactive elementsrich-megabyte-73517
04/15/2026, 10:32 PMtall-airline-16756
04/15/2026, 10:33 PM/stats endpoint: curl http://<livekit-host>:7880/stats to see registered agents, worker load values, active_jobs, and session counts.
• Agent health endpoint: curl http://<agent-host>:8081/ — returns 200 when the agent is healthy.
• Logs: check LiveKit server logs for agent registration lines and agent process/container logs for “registered”, “draining”, or error messages.
Programmatic monitoring
• Poll /stats from your code (HTTP GET) and parse JSON to track:
◦ number of registered agents/workers
◦ load value per worker
◦ active_jobs (sessions)
◦ health status
• Example (Python, minimal):
import requests
resp = requests.get("http://<livekit-host>:7880/stats")
data = resp.json()
# inspect agents, active_jobs, and load values in data
Metrics & observability options
• Expose and collect Prometheus metrics if you run a metrics stack; track CPU, memory, and active_jobs.
• Use LiveKit Agent Observability (if available) or your dashboard to view session traces, transcripts, and per-job latency.
• Monitor autoscaling triggers (CPU or custom metric) and load relative to load_threshold (default 0.7).
What to watch for
• Agents not listed in /stats → registration/network problem.
• Workers showing load ≥ 0.7 → they will stop accepting new jobs.
• High active_jobs with high CPU → scale up or reduce per-worker concurrency.
• Repeated “draining” or health failures in logs → investigate shutdown or startup issues.
Next step
• Tell me which you want: a Python script to poll /stats regularly, a Prometheus scrape config example, or help interpreting a redacted /stats output — I’ll provide the snippet. Sources: Server options | LiveKit Documentation | Understand and Improve Agent Latency | LiveKit | Agent deployment overview | LiveKit Documentation | LiveKit Agent Observability | Debug and optimize voice agents | LiveKit | Deployment reliability on LiveKit Cloud | LiveKit, with interactive elementsrich-megabyte-73517
04/15/2026, 10:45 PMtall-airline-16756
04/15/2026, 10:45 PMon_request / rtc_session) — do not call subprocess.Popen.
• Prewarm heavy models in startup/setup hooks so job subprocesses avoid cold starts.
• Control concurrency with the default CPU-based load_fnc or a custom load_fnc (e.g., active_jobs / N) and scale workers via your orchestration, not by spawning processes.
Minimal Python pattern
server = AgentServer()
@server.rtc_session(agent_name="my-agent")
async def handler(ctx):
# session logic here — no subprocesses
...
server.start()
If you paste your current agent start code and subprocess snippet, I’ll show the exact edits to remove manual subprocesses and run N workers cleanly.
, with interactive elements