most-furniture-64179
03/03/2026, 4:34 PMtall-airline-16756
03/03/2026, 4:34 PMtall-airline-16756
03/03/2026, 4:34 PMmost-furniture-64179
03/03/2026, 5:25 PMmost-furniture-64179
03/03/2026, 5:25 PMtall-airline-16756
03/03/2026, 5:26 PMdisconnect or being backgrounded/suspended before cleanup (mobile apps).
• Network interruptions causing clients to appear connected on server side while application state thinks they left.
• Middle-tier or bot processes (TTS/STT) creating persistent connections and not closing them.
• Dashboard/UI bug showing incorrect duration while actual participant connections are short-lived.
Next steps I recommend
• Share one example warning email and one example participant/room log (timestamps) so I can point to exactly where session state diverges.
• Confirm SDK versions and whether bots (TTS/STT) run as persistent participants.
• If you want, I can give the exact API call to force-disconnect a participant once you provide a participant SID and project/room ID.
If you prefer, tell me one room/session ID that’s showing the long duration and what you see when you open it — I’ll give precise commands you can run to inspect or force-remove participants.most-furniture-64179
03/03/2026, 5:42 PMUsage warning: 80% of demo's concurrent STT connections on LiveKit used
Hi Karan Dhir,
Your project demo has recently reached 40 concurrent STT connections, which is nearing the limit of 50. To avoid service disruption for your users, please review your options in the settings page for your project.
2. Here's a session link https://cloud.livekit.io/projects/p_5oyry9787wp/sessions/RM_Fk7b6esXQakY/observability?mode=transcript
4. No we are not
5.SDKs & Versions
Server-side (Node.js voice agent):
┌──────────────────────────────────┬──────────┐
│ Package │ Version │
├──────────────────────────────────┼──────────┤
│ @alert-easter-19258/agents │ ^1.0.47 │
├──────────────────────────────────┼──────────┤
│ @alert-easter-19258/agents-plugin-livekit │ ^1.0.47 │
├──────────────────────────────────┼──────────┤
│ @alert-easter-19258/agents-plugin-silero │ ^1.0.47 │
├──────────────────────────────────┼──────────┤
│ @alert-easter-19258/rtc-node │ ^0.13.24 │
├──────────────────────────────────┼──────────┤
│ @alert-easter-19258/noise-cancellation-node │ ^0.1.9 │
├──────────────────────────────────┼──────────┤
│ @alert-easter-19258/protocol │ ^1.44.0 │
├──────────────────────────────────┼──────────┤
│ livekit-server-sdk │ ^2.15.0 │
└──────────────────────────────────┴──────────┘
Client-side (Web/React):
┌───────────────────────────┬─────────┐
│ Package │ Version │
├───────────────────────────┼─────────┤
│ livekit-client │ ^2.17.0 │
├───────────────────────────┼─────────┤
│ @alert-easter-19258/components-react │ ^2.9.19 │
└───────────────────────────┴─────────┘
No iOS/Android SDKs — web only.tall-airline-16756
03/03/2026, 5:43 PMsession.shutdown() / session.aclose() will keep holding inference resources and count against concurrency even if media stopped.
• Crashed processes, unhandled errors, or missing shutdown paths (including when a client is backgrounded or a network drop happens) can leave sessions logically open.
• Long-lived server-side agents (TTS/STT workers) can create many concurrent inference calls if they’re not drained/closed properly.
• The dashboard can show a room/session lifetime that looks long while participant connections have already disconnected — that indicates the session object itself wasn’t finalized.
Immediate diagnostics to run (quick checks)
1. Confirm participant state in the session observability page
◦ Open the session observability link you gave and check the participant list/state. Does it show participants as Connected or Disconnected? If participants show Disconnected but session duration is long, that implies the session object is still open.
1. Inspect agent lifecycle events and logs for the same timestamps
◦ Look for agent_state_changed and close or shutdown events around those sessions. If you don’t see a shutdown event, the session didn’t finalize.
1. Search for active inference jobs or long-running AgentSession objects in your server logs
◦ Look for repeated STT start/stop messages, unhandled exceptions, or missing shutdown calls in your Node.js agent logs.
1. Confirm whether your voice agent creates multiple inference sessions per user
◦ Server-side logic can spawn parallel STT streams (one per audio source or task). Verify how many inference sessions you spawn per incoming connection.
How to safely clean up stuck sessions right now
1. Manually force-disconnect a stuck participant (if you have the participant SID)
◦ Use the admin API to disconnect a participant or delete the room. If you tell me one participant SID or the room ID you want to target, I’ll give the exact API call you can run.
1. If you can’t use the API, restart the agent process that owns those sessions
◦ Restarting a process will drop its open inference connections and free concurrency slots.
1. For sessions created by your agent code, explicitly call graceful shutdown
◦ Use session.shutdown(drain=true) or ctx.shutdown(drain=true) so queued operations finish before closing.
1. If you see sessions in the dashboard that show long durations but no connected participants, manually delete the room/session from the dashboard to force cleanup.
Code/lifecycle checks to prevent recurrence
• Ensure every AgentSession exit path calls session.shutdown() / session.aclose(), including error handlers and signals.
• Use ctx.add_shutdown_callback() to run cleanup tasks even if an error occurs.
• Listen for agent_state_changed and close events and emit logs when sessions enter terminal states.
• Avoid spawning unnecessary parallel inference calls; batch or serialize STT where possible.
• If you run TTS/STT bots as persistent participants, consider reusing a single inference connection or limiting concurrency per bot.
Plan / limit considerations
• Inference concurrency is a plan-limited, hard cap. If your usage legitimately needs more concurrency you’ll need to upgrade your plan. If you don’t need it, cleaning up leaked sessions will prevent hitting the cap.
Next diagnostic help I can provide
• If you paste one participant SID or a room/session ID that currently appears stuck (or tell me whether the observability page shows participants as connected/disconnected), I’ll give the exact API command to force-disconnect and the exact shutdown snippet to add to your agent code.
• If you paste a short log trace around one problematic session (join time, any errors, missing shutdown), I’ll point to the exact missing lifecycle event to fix.
If you want, start by telling me:
• A single room ID or participant SID that looks wrong (from your observability page), and
• Whether that session’s participant shows Connected or Disconnected in the observability UI.
I’ll reply with the exact commands/snippets to force cleanup and the minimal code changes to ensure sessions are always closed gracefully.
Sources: How much can LiveKit scale? | LiveKit | Job lifecycle | LiveKit Documentation | Agent Builder | LiveKit Documentation | Collect recording consent with tasks | LiveKit Documentation | Agent session | LiveKit Documentationmost-furniture-64179
03/03/2026, 8:59 PMlivekit:dev / npx tsx ... dev) and hitting Ctrl+C, we get an unhandled EPIPE crash:
Error: write EPIPE
at target._send (node:internal/child_process:877:20)
at target.send (node:internal/child_process:751:19)
at <anonymous> (node_modules/@livekit/agents/dist/ipc/inference_proc_lazy_main.js:81:21)
followed by:
libc++abi: terminating due to uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument
What's happening: SIGINT hits both the CLI and inference processes simultaneously. The CLI shuts down the worker and closes the IPC pipe, but the inference process (inference_proc_lazy_main.js:81) still tries to process.send() back — pipe is gone, unhandled EPIPE, which cascades into the native RTC addon mutex crash.
Running through a process manager (like turborepo's turbo watch) that sequences the shutdown signals avoids this since the IPC pipes are still intact when children communicate. So it's not blocking us day-to-day, but it does make local dev mode less clean.
SDK version: @livekit/agents 1.0.47, Node 22.14.0, macOS
Seems like wrapping that process.send in a try-catch or adding a process.on('error') handler in the inference proc would fix it.tall-airline-16756
03/03/2026, 8:59 PM