2 different sessions with same room name are getti...
# ask-ai
b
2 different sessions with same room name are getting created with SIP outbound trigger, why is this happening
t
Thanks for reaching out, Vineeth. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I’m sorry you’re seeing two sessions created with the same room name. I’ll explain the common reasons this happens with SIP outbound triggers and give concrete steps you can take to avoid it. What’s causing this • Room name reuse does not guarantee a unique Room ID. When a room is deleted and a new room is created quickly with the same name, the system can non-deterministically reuse the previous internal Room ID. • Race condition between deletion and recreation. The DeleteRoom flow marks the room as ended, but if a CreateRoom request arrives before the database cleanup is complete, the system may treat the old room as still active and produce overlapping state that looks like duplicate sessions. • Auto-termination and sweeper delay. If you rely on automatic room closing (no explicit DeleteRoom), rooms are closed after a departure timeout (default ~20s) and a background sweeper finalizes cleanup (can take 30–45s). Creating a room within that window increases the chance of reuse. • SIP outbound workflow patterns. If your SIP outbound logic (agent dispatch or CreateSIPParticipant) uses a static room name for repeated calls or retries, rapid call sequences can trigger the above behaviors and result in multiple sessions sharing the same name. What you can do right now • Use unique room names (recommended): Append a timestamp, UUID, or short random string to the base name so every CreateRoom request generates a distinct room. Example patterns:
user_12345_20250318T150405Z
or
user_12345_ab12cd34
. This guarantees separate Room IDs and avoids ambiguity. • If you must reuse names: add a delay before recreating the same name. Wait at least 1–2 minutes after deleting or after all participants leave so the sweeper finishes cleanup. • Review SIP outbound logic: ensure the agent dispatch / CreateSIPParticipant code creates a new unique room per outbound call (rather than reusing a static name) or explicitly calls DeleteRoom and waits before recreating. If you want, I can help with next steps • If you’d like, share how your SIP trigger currently constructs room names (example format) and whether you call DeleteRoom explicitly. I can suggest a safe naming pattern and where to add delays. • If you prefer, I can outline code-level approaches to generate unique names or add a short retry/backoff before recreating a room. Would you like me to review your naming/creation flow or propose a specific naming pattern for your use case? Sources: Avoiding Room ID Reuse When Re-Creating Rooms With the Same Name | Outbound Calling Script | LiveKit Documentation | Agents telephony integration | LiveKit Documentation | Building an Automated IVR Menu Caller | LiveKit Documentation, with interactive elements
b
Both the sessions with same room names started at the exact same timestamp according to livekit cloud logs
t
Thanks — that detail helps. Seeing two sessions with the exact same timestamp in the LiveKit Cloud logs confirms the creation requests happened concurrently, and that points to concurrency/race behavior rather than a delayed cleanup alone. Below I’ll explain what that means and give concrete next steps you can take. What the identical timestamps indicate • Concurrent CreateRoom requests: Two separate CreateRoom (or SIP-triggered room-creation) requests for the same room name were received at essentially the same time, so the system processed both and produced distinct sessions. • LiveKit permits multiple rooms with the same name. Room names are not enforced as globally unique at the moment of creation, so simultaneous creations can result in distinct internal Room IDs but the same visible name. • This is different from the “reuse after delete” scenario — identical timestamps point to simultaneous creation rather than reuse after an earlier deletion. Why this happens in SIP outbound flows • If your SIP outbound trigger or dispatch logic sends parallel requests (retries, duplicate webhooks, or two agents triggering the same job) those can create two rooms at once. • If the SIP integration calls
CreateSIPParticipant
or CreateRoom without a uniqueness guard, two nearly-simultaneous calls will both succeed and create separate sessions that look identical by name and start time. Practical fixes you can apply now • Make room names unique per call (recommended): Append a short unique suffix (UUID, timestamp, or call-id). This fully prevents collisions even for concurrent requests. Example:
user_12345_20260318T150405Z
or
user_12345_ab12
. • Add a creation guard in your SIP flow: Before creating a room, check for an in-progress create for the same logical call ID and block duplicate create attempts for a short window (e.g., 1–2 seconds). • Deduplicate incoming triggers: If your SIP provider or orchestration can send duplicate webhooks, deduplicate by call-id or webhook-id at the edge before calling LiveKit. • Use an atomic server-side create: If possible, route all CreateRoom requests through a single server-side service that can enforce uniqueness (for example, by using a lock or checking a datastore key) before sending the LiveKit create call. If you’d like, I can help with either: • A suggested room-name pattern (UUID vs timestamp vs call-id) for your flow, or • A short example approach to deduplicate create requests (pseudo-code or sequence steps) that you can implement in your SIP trigger service. Which would you prefer me to draft for you? , with interactive elements
b
My logs definitely confirm CreateSIPParticipantRequest was only triggered once for this room and number, there was supposed to be one room and session only but livekit internally has somehow created 2 sesisons, I can also confirm that this happens very randomly which is like 1 in 10 or 100 calls and very randomly, other calls with same code create only one room and everything is fine
t
Thanks — that’s a helpful confirmation, and I understand why this intermittent behavior is worrying. You’ve said CreateSIPParticipantRequest fires only once, but LiveKit sometimes creates two sessions for the same room/name (roughly 1 in 10–100 calls). I’ll explain likely causes, suggest concrete diagnostics you can collect, and give mitigations to reduce or eliminate the duplicates. What this pattern suggests • Concurrent internal processing or edge race: Even with a single incoming request, internal retries, timeouts, or concurrent background operations can rarely cause LiveKit to create two sessions with the same visible name but different internal IDs. Because it’s intermittent and rare, this points to a timing/race edge case rather than deterministic logic in your caller flow. • Transient networking or retry behavior: If a client or intermediary times out waiting for an acknowledgement and retries the Create call (even if your logs show only one outward CreateSIPParticipantRequest), retries can occur inside networking layers (load balancers, proxies, or the SIP integration) or as a result of the SIP provider retransmitting. Those retries may not appear in the same log stream you checked. • Internal cleanup / concurrent lifecycle flows: If a previous room instance is just finishing teardown while a new create occurs, the system can end up with overlapping sessions with identical names in rare cases. Diagnostics I recommend (these will help pinpoint root cause) 1. Correlate full request/response traces: ◦ Capture the full upstream request/response for the CreateSIPParticipantRequest including headers, request-id/tracing IDs, and the exact timestamp (ms precision). ◦ Collect LiveKit Cloud logs for the same time window (±30s) and filter on any request IDs, client IPs, or room names. 1. Check for duplicates at intermediate layers: ◦ Inspect any load balancer, API gateway, or reverse proxy logs for the same timeframe to see whether it retried or forwarded the request twice. ◦ Check your SIP provider webhook delivery logs to confirm only one webhook arrived at your service and whether it shows any retries. 1. Capture LiveKit internal events around the time of creation: ◦ If possible, include the LiveKit response payload(s) to the create call(s). If two rooms were created, there will be two distinct Room IDs returned. Save those IDs and the full create responses. 1. Reproduce with verbose logging: ◦ Temporarily add more detailed tracing around CreateSIPParticipant/room creation: log unique local request IDs, timestamps with ms precision, and any retry/backoff decisions. ◦ If you can reproduce in a lower-volume environment, enable debug-level logs and try to generate the race by firing calls at higher concurrency. 1. Note environmental patterns: ◦ Are duplicates correlated with higher system load, particular regions, specific numbers, or particular SIP carriers? Any pattern helps isolate where the race occurs. Immediate mitigations you can deploy • Add an idempotency guard on your side: Before calling LiveKit to create a room/participant, insert a short-lived lock keyed by the logical call ID (e.g., call_id or phone number + timestamp). This prevents concurrent/process-level duplicate creates even if an internal retry happens. • Create unique room names per call (safest): Append a short random suffix or the SIP call-id so even if two creates occur, they won’t collide and you won’t get confusing duplicate visible names. • Implement a server-side dedupe window: If you detect two rooms created for the same logical call, choose one room to use and programmatically end the other via DeleteRoom so downstream systems see only one active session. If you want, I can: • Draft a small idempotency pseudocode example using a lock/store (Redis, DB row with unique constraint, etc.). • Review any snippets of your create flow (timestamps, request/response pairs, any request IDs) and point out likely places where a retry or duplicate could slip in. • Propose a naming or dedup strategy that fits your current SIP flow. Which would be most helpful right now — a short idempotency code example, or help examining specific logs/IDs you can paste here? , with interactive elements
b
I am triggering create sip participant with a room name only once, how does different room name here help if livekit internally has race conditions
t
Thanks — that’s a great question. I understand why it feels like using a different room name shouldn’t matter if the duplication is an internal LiveKit race. Let me explain why a unique name helps, what the internal race likely looks like, and practical steps you can take so you don’t see duplicate visible sessions while we investigate the root cause. Why a unique room name helps (even with an internal race) • LiveKit creates an internal Room ID for every successful create. The visible room name is a user-facing label that can be reused across different internal Room IDs. If two creates proceed concurrently, LiveKit can end up with two distinct Room IDs that share the same visible name. • If you always give each create a unique visible name, any concurrent duplicate create will produce two rooms with different visible names. That means you won’t observe confusing “two sessions with the same name” in your logs or downstream systems — you’ll see two distinct names and can easily detect and discard the unexpected one. • In short: unique names do not prevent the internal race from happening, but they prevent the symptom that is causing confusion and misrouting (identical name + identical timestamp). What the internal race likely looks like • A single upstream CreateSIPParticipantRequest arrives and LiveKit’s processing path executes concurrent internal operations (for example, separate subsystems creating room state, creating participant records, or acknowledging before finalizing persistence). In a rare timing window, these operations can create two distinct Room objects with the same visible name. • Because this is intermittent, it’s likely a timing/race edge in concurrent processing on the LiveKit side (or an internal retry path that ends up creating a second room) rather than an obvious duplicate request from your side. How to stop the visible problem immediately (practical mitigations) • Use unique room names per call (recommended, low friction): Append a short suffix like a UUID, the SIP call-id, or a millisecond timestamp to your base name. This makes any concurrent internal duplicate obvious and non-conflicting. Example:
order_12345_7f3b
or
call-<callid>
. • Add a server-side idempotency/lock (recommended for full protection): Before calling LiveKit, set a short-lived lock keyed by your logical call identifier (call-id, phone number + time window). If the lock exists, skip the create. Use Redis, a DB row with unique constraint, or any central store. This prevents duplicate create attempts reaching LiveKit even if internal retries or duplicate webhooks occur. • Short dedupe window after create: After you receive the create response, monitor for a second room with the same call identifier within a small window (a few seconds). If a duplicate appears, programmatically DeleteRoom for the unwanted one and continue with the correct room. • Improve observability: Emit a unique request-id with your CreateSIPParticipantRequest and log it both at your edge and include it when you call LiveKit (if possible). That makes correlating any dual-creation in LiveKit logs deterministic. Tradeoffs — why choose each option • Unique names: Quick to implement, prevents confusion, doesn’t mask the underlying bug but avoids operational impact. • Idempotency/locks: Strong protection that prevents duplicates entirely at the source, slightly more engineering (store + lock logic). • Dedup & cleanup: Works as a fallback if duplicates still appear; allows automatic correction after the fact. If you’d like, I can: • Draft a small idempotency pseudocode example (Redis or DB) you can drop into your SIP trigger path. • Propose a naming pattern that fits your workflow (short vs verbose suffixes). • Help analyze specific timestamps/room IDs if you paste the create response(s) and the LiveKit room IDs you observed. Which do you want next — a short idempotency code snippet or a suggested naming pattern tailored to your flow? , with interactive elements
b
I will give you one more input, 2 different sessions with same room name created and agent was dispatched to only one, participant joined in that room etc
t
Thanks — that extra detail (agent dispatched to only one of the two sessions and the participant joined that room) is very useful. I know this is frustrating when you expect a single session per call. Below I’ll explain why only one session received the agent, what that tells us about the internal behavior, and concrete steps you can take to prevent the operational impact while we investigate further. What the behavior indicates • Single agent dispatch to one room: This shows the agent routing logic picked one of the two internal Room IDs as the “active” session. The other room likely remained unpopulated (no agent routed to it) or was created slightly out of sync with your agent dispatch decision. That’s consistent with an internal race resulting in two distinct Room IDs that share the same visible name. • Participant joined the room that had the agent: The participant and agent ended up in the same Room ID, so from an end-user perspective the call worked — but the extra, unused room is the confusing artifact. • Intermittent occurrence: Because it’s rare and random, it strongly suggests a timing/race edge inside the create/process pipeline rather than a deterministic logic bug in your dispatch code. Why only one room got the agent • Agent dispatch likely used the first successful room creation or the room state that appeared earliest to your dispatch system. If two rooms are created nearly simultaneously, dispatch logic (or your matching key) will choose one — typically the one it sees first. The other room is left orphaned. • If your dispatch flow relies on the visible room name to identify rooms, duplicate visible names make it ambiguous which internal Room ID to use; dispatch may simply pick the first matching room it discovers. Concrete mitigations (short-term and recommended) • Make visible room names unique per call (recommended quick fix) ◦ Append a small unique suffix (UUID, SIP call-id, or timestamp in ms) to each room name so any concurrent duplicate create yields distinct visible names. That prevents confusion and ensures your dispatch logic can deterministically choose the intended room. • Add an idempotency/locking guard before create (recommended for full protection) ◦ Use a short-lived lock keyed by the logical call id (call-id, phone number+time window) in Redis or your DB. If the lock exists, skip creating a room. This prevents duplicate or concurrent creates from producing multiple rooms. • Deduplicate and cleanup after create (safety net) ◦ After receiving the create response, monitor for any second room created with the same call identifier within a short window (e.g., 5–10s). If a duplicate appears, programmatically DeleteRoom for the unwanted room so downstream systems see only one active session. • Make dispatch use the returned Room ID (not only name) ◦ If your agent dispatch consumes the create response, use the Room ID returned by LiveKit to route the agent. Relying on the visible name alone leaves you vulnerable to name collisions. • Improve observability ◦ Emit and propagate a unique request-id with your create call and log it across your stack and with LiveKit responses. This makes it straightforward to correlate which create produced which Room ID and why an orphaned room was created. If you want, I can provide: • A short idempotency pseudocode example using Redis (lock + TTL) you can drop into your SIP trigger. • A suggested naming pattern that minimally changes your flow (e.g., append 8 hex chars of randomness or the SIP call-id). • Guidance for a small dedupe/cleanup routine you can run after create. Which would be most helpful right now — the idempotency pseudocode, the naming pattern suggestion, or a cleanup/dedup example? If you can paste one of the create responses and the two Room IDs/timestamps, I can also point out what to look for in logs to correlate them quickly. , with interactive elements
b
There is nothing from my end I can do for this to avoid since this seems to be a livekit internal timing issue but I want to handle egress properly for this, if there are 2 rooms with the same name then egress returns room not found. await egress.start_room_composite_egress( start=api.RoomCompositeEgressRequest( _room_name_=ctx.room.name, layout="speaker", preset=api.EncodingOptionsPreset.H264_720P_30, _audio_only_=True, _file_outputs_=[ api.EncodedFileOutput( _file_type_=api.EncodedFileType.MP4, filepath=file_path, s3=api.S3Upload( bucket=settings.AWS_BUCKET_NAME, region=settings.AWS_REGION, _access_key_=settings.AWS_ACCESS_KEY_ID, secret=settings.AWS_SECRET_ACCESS_KEY, _force_path_style_=True, ), ) ], ) ) how do I change this to handle the correct room out of both duplicate rooms
t
Thanks — that’s clear and helpful. I’ll respond to the part about changing your egress call so it reliably targets the correct session when two rooms exist with the same visible name. Short answer: don’t rely on room name for egress when duplicates are possible — resolve the correct room’s unique room_id first, then start egress for that specific room. Since the SDK call you showed accepts
room_name
, you should instead determine the correct
room_id
(via ListRooms or the room_started webhook) and use that ID to select the session to record or to call any egress API that accepts room identity (or use the room’s metadata to pick the right name-to-id mapping before calling egress). What to do step-by-step 1. Identify the correct room_id for this call ◦ Use ListRooms (or an equivalent API) filtered by the visible room name and pick the right instance: ▪︎ Prefer the room whose
started_at
or
creation_time
matches when your agent/participant joined. ▪︎ Prefer the room that has the participant or agent currently present (check participants list). ◦ Or, subscribe to the
room_started
webhook and cache the latest
room_id
for each logical call. Webhooks include both
room_name
and
room_id
, which gives an authoritative mapping at start time. 1. Use that room_id to pick the single correct session ◦ If you get two matches from ListRooms, choose the one with: ▪︎ the agent and participant present, or ▪︎ the latest creation/started timestamp that corresponds to your call, or ▪︎ the room_id you received earlier from the create response or webhook. 1. Start egress for that room/session ◦ If your SDK or API supports passing
room_id
directly to start egress, pass the found
room_id
. ◦ If the SDK currently accepts only
room_name
, call the higher-level egress API or an admin endpoint that accepts
room_id
, or use the room_name only after you’ve ensured only one active room_name -> room_id mapping (by deleting/stopping any duplicate). ◦ As a fallback, once you have the correct
room_id
, programmatically DeleteRoom for any other room_id with the same name (if it’s safe to do so) so
room_name
resolves to a single session before calling
start_room_composite_egress
. Practical examples (patterns) • Preferred (if API supports room_id): a. Call ListRooms or listen to
room_started
and get
room_id
= RM_xxx. b. Call egress.start with that
room_id
. • If SDK only has `room_name`: a. Use ListRooms to get all rooms with that name. b. Select the correct
room_id
by timestamps or participant presence. c. If possible, use an admin API to start egress by room_id; otherwise: • Delete the other room(s) you know are duplicates (DeleteRoom by room_id) so the
room_name
maps to the right session. • Then call start_room_composite_egress with
room_name
. Observability and selection rules (to pick the right instance reliably) • Match by participant list: prefer the room that currently shows the participant/agent as connected. • Match by timestamp: select the room whose start time is closest to when your participant or agent joined. • Use call metadata: include a unique call-id in participant metadata and use that to locate the right room instance. Safety notes • Only DeleteRoom duplicates when you are certain they are orphaned, otherwise you may interrupt a legitimate session. • If you choose automatic cleanup, add a short cooldown so you don’t remove a session still in use. Offer to help • I can draft a short pseudocode snippet for: ◦ Listing rooms and selecting the correct
room_id
by participant presence/timestamps, and ◦ Starting egress using that chosen
room_id
(or deleting duplicates then calling your existing
room_name
-based egress). • If you paste a sample of your ListRooms response or two room objects (room_id, started_at, participants), I can point out exactly which one to choose and show the API calls in code. Which would you like — a pseudocode example for ListRooms + select + egress, or a webhook-based approach that caches room_id at start time? Sources: Avoiding Room ID Reuse When Re-Creating Rooms With the Same Name | Python SDKs | livekit/livekit_composite | DeepWiki | server-sdk-js | livekit/livekit_composite | DeepWiki, with interactive elements
b
One more input from my create sip participant is it took 5 seconds for await self.lk_api.sip.create_sip_participant(req) to return, I am guessing something timed out internally in livekit or something leading to duplicate room creation
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!