Skip to content

Instantly share code, notes, and snippets.

@ChakshuGautam
Last active November 12, 2025 07:40
Show Gist options
  • Select an option

  • Save ChakshuGautam/92c31f271c95747b56aff03ca52d5d1c to your computer and use it in GitHub Desktop.

Select an option

Save ChakshuGautam/92c31f271c95747b56aff03ca52d5d1c to your computer and use it in GitHub Desktop.
Complete RCA Timeline with LiveKit Egress & Streaming Backend Logs - Nov 11, 2025

Complete Timeline Analysis with LiveKit Egress & Streaming Backend Logs

Nov 11, 2025 - 6:00 PM to 7:00 PM IST (12:00-14:00 UTC)


Executive Summary

CRITICAL FINDING: Meeting 1 and Meeting 2 did NOT overlap. There was NO localStorage collision or dual-recording conflict.

  • Meeting 1: Started at 6:07 PM IST, ended at 6:44 PM IST (36 minutes 45 seconds)
  • Meeting 2: Started at 6:54 PM IST, ended at 6:54 PM IST (9 seconds)
  • Gap between meetings: 10 minutes

User's statement was accurate: "One of the meetings started around ~6:08 PM IST 11th Nov. Ended at 6:44 PM IST due to start of another meeting on a different tab"

However, the logs show Meeting 2 started 10 minutes AFTER Meeting 1 ended, not "due to" Meeting 2 starting.


Complete Timeline (UTC → IST)

12:37:57 UTC (6:07:57 PM IST)

Meeting 1: Room Created

[Streaming Backend] ✅ Room created: meeting-meeting_1762864213167_td07i9w3w
  • User opened first tab
  • LiveKit room created on server

12:37:58 UTC (6:07:58 PM IST)

Meeting 1: User Token Generated

[Streaming Backend] ✅ Token generated for Simran in room meeting-meeting_1762864213167_td07i9w3w
  • Participant name: Simran
  • Ready to join LiveKit room

12:38:00 UTC (6:08:00 PM IST)

Meeting 1: Bot Token Generated

[Streaming Backend] ✅ Token generated for 🤖 Room Keeper in room meeting-meeting_1762864213167_td07i9w3w
  • Room Keeper bot joined to prevent empty room closure

12:38:03 UTC (6:08:03 PM IST) ⭐

Meeting 1: Recording Requested

[LiveKit Egress] request received {"egressID": "EG_5HnBcxZK8hHV"}
[LiveKit Egress] request validated {
  "requestType": "room_composite",
  "sourceType": "EGRESS_SOURCE_TYPE_WEB",
  "outputType": "file",
  "room": "meeting-meeting_1762864213167_td07i9w3w",
  "audio_only": true,
  "audio_bitrate": 64,
  "filepath": "recordings/meeting-meeting_1762864213167_td07i9w3w-{time}.webm"
}

[Streaming Backend] ✅ Participant recording started for Simran, egressId: EG_5HnBcxZK8hHV
  • Egress ID: EG_5HnBcxZK8hHV
  • Format: WebM (audio only)
  • Bitrate: 64 kbps
  • User statement confirmed: Recording started at ~6:08 PM IST

12:38:05 UTC (6:08:05 PM IST)

Meeting 1: Chrome Recording Started

[LiveKit Egress] chrome: START_RECORDING {"egressID": "EG_5HnBcxZK8hHV"}
[LiveKit Egress] pipeline playing
[LiveKit Egress] egress_active
  • LiveKit opened headless Chrome browser
  • Audio capture pipeline activated
  • Recording officially active

12:38:05 - 13:14:42 UTC (6:08 - 6:44 PM IST)

Meeting 1: Active Recording 🔴

  • Duration: 36 minutes 37 seconds
  • Participant: Simran
  • No interruptions
  • No errors in logs

13:14:42 UTC (6:44:42 PM IST) ⭐

Meeting 1: Recording Stopped

[LiveKit Egress] egress_ending {
  "egressID": "EG_5HnBcxZK8hHV",
  "requestType": "room_composite",
  "outputType": "file",
  "error": "",
  "code": 0,
  "details": "End reason: StopEgress API"
}
[LiveKit Egress] pipeline received EOS (End of Stream)

[Streaming Backend] ✅ Recording stopped: EG_5HnBcxZK8hHV
  • End reason: StopEgress API (user clicked "End Recording")
  • NOT killed by another meeting
  • User statement confirmed: Recording ended at 6:44 PM IST

13:14:42 - 13:15:39 UTC (6:44 - 6:45 PM IST)

Meeting 1: Post-Processing ⚙️

Step 1: LiveKit Egress Completion

[LiveKit Egress] egress_complete {
  "egressID": "EG_5HnBcxZK8hHV",
  "details": "End reason: StopEgress API"
}
  • WebM file finalized
  • Uploaded to streaming backend

Step 2: WebM to MP3 Conversion

[Streaming Backend] 📊 [SSE Progress] Step 5: Converting to MP3 format...
  4.2% complete (21.1x speed)
  10.4% complete (26.5x speed)
  17.6% complete (29.9x speed)
  25.0% complete (31.7x speed)
  32.6% complete (33.2x speed)
  40.3% complete (34.2x speed)
  46.9% complete (34.1x speed)
  53.9% complete (34.3x speed)
  60.9% complete (34.4x speed)
  68.0% complete (34.6x speed)
  75.6% complete (35.0x speed)
  82.2% complete (34.8x speed)
  89.5% complete (34.6x speed)
  96.1% complete (34.5x speed)
  • Conversion speed: ~34x realtime
  • Processing: WebM → MP3 (FFmpeg)

Step 3: Multiple Conversion Passes

[Streaming Backend] ✅ Conversion complete in 44.27s
✅ Conversion complete in 41.69s
✅ Conversion complete in 49.29s
  • Why 3 conversions? Likely processing pause periods separately
  • Total processing time: ~135 seconds (~2 minutes 15 seconds)

13:15:39 UTC (6:45:39 PM IST)

Meeting 1: Upload Complete

[Streaming Backend] ✅ Upload complete in 4.90s
URL: https://pmctogcsukpjqehm.public.blob.vercel-storage.com/meeting-meeting-meeting_1762864213167_td07i9w3w-1762866933600-fwTVcdnCSb4usnNiMUORmOImqKWhie.mp3

✅ Updated meeting meeting_1762864213167_td07i9w3w with audio URL
✅ [SSE] Meeting meeting_1762864213167_td07i9w3w updated with audio URL
✅ Recording result saved to /app/recording-status/meeting_1762864213167_td07i9w3w.json

🔀 Merge request for meeting meeting_1762864213167_td07i9w3w
   Egress URL: [same as above]
   Audio URL: [same as above]
  • Audio uploaded to Vercel Blob
  • Database updated with audio URL
  • Frontend notified via SSE
  • Recording status file saved

10-Minute Gap (6:45 - 6:54 PM IST)

No activity logged - User likely:

  1. Reviewed Meeting 1 recording
  2. Opened new tab for Meeting 2
  3. Prepared for second meeting

13:24:28 UTC (6:54:28 PM IST)

Meeting 2: Room Created

[Streaming Backend] ✅ Room created: meeting-meeting_1762867368498_riizxm5te
  • User opened second tab
  • Meeting 1 had already ended 10 minutes ago
  • No conflict with Meeting 1

13:24:28 UTC (6:54:28 PM IST)

Meeting 2: User Token Generated

[Streaming Backend] ✅ Token generated for Host in room meeting-meeting_1762867368498_riizxm5te
  • Participant name: Host (different from Meeting 1's "Simran")

13:24:34 UTC (6:54:34 PM IST)

Meeting 2: Bot Token Generated

[Streaming Backend] ✅ Token generated for 🤖 Room Keeper in room meeting-meeting_1762867368498_riizxm5te

13:24:36 UTC (6:54:36 PM IST)

Meeting 2: Recording Requested

[LiveKit Egress] request received {"egressID": "EG_VEGAkU29oGkn"}
[LiveKit Egress] request validated {
  "requestType": "room_composite",
  "room": "meeting-meeting_1762867368498_riizxm5te",
  "audio_only": true,
  "audio_bitrate": 64
}

[Streaming Backend] ✅ Participant recording started for Host, egressId: EG_VEGAkU29oGkn
  • Egress ID: EG_VEGAkU29oGkn (different from Meeting 1)
  • Same configuration as Meeting 1

13:24:39 UTC (6:54:39 PM IST)

Meeting 2: Chrome Recording Started

[LiveKit Egress] chrome: START_RECORDING {"egressID": "EG_VEGAkU29oGkn"}
[LiveKit Egress] pipeline playing
[LiveKit Egress] egress_active

13:24:45 UTC (6:54:45 PM IST)

Meeting 2: Recording Stopped

[LiveKit Egress] egress_ending {
  "egressID": "EG_VEGAkU29oGkn",
  "details": "End reason: StopEgress API"
}
[LiveKit Egress] pipeline received EOS
[LiveKit Egress] egress_complete

[Streaming Backend] ✅ Recording stopped: EG_VEGAkU29oGkn
  • Duration: Only 9 seconds of recording!
  • User quickly stopped (likely a test or accidental start)

13:24:48 UTC (6:54:48 PM IST)

Meeting 2: Processing Complete

[Streaming Backend] ✅ Conversion complete in 0.25s
✅ Upload complete in 0.75s
URL: https://pmctogcsukpjqehm.public.blob.vercel-storage.com/meeting-meeting-meeting_1762867368498_riizxm5te-1762867488190-LirnXzdPuaQB41OC9Aw9JZr7nhSxGE.mp3
  • Very fast processing (only 1 second total)
  • Audio file size: 0.16 MB

13:24:49 UTC (6:54:49 PM IST)

Meeting 2: Upload Complete

[Streaming Backend] ✅ Updated meeting meeting_1762867368498_riizxm5te with audio URL
✅ [SSE] Meeting meeting_1762867368498_riizxm5te updated with audio URL
✅ Recording result saved to /app/recording-status/meeting_1762867368498_riizxm5te.json

Key Findings

1. No Collision Occurred ✅

Meeting 1 Timeline:

  • Started: 12:38:03 UTC (6:08 PM IST)
  • Ended: 13:14:42 UTC (6:44 PM IST)
  • Processing finished: 13:15:39 UTC (6:45 PM IST)

Meeting 2 Timeline:

  • Started: 13:24:36 UTC (6:54 PM IST)
  • Ended: 13:24:45 UTC (6:54 PM IST)

Gap: 9 minutes 54 seconds between Meeting 1 ending and Meeting 2 starting

Conclusion: The meetings were completely separate with no overlap.

2. Both Meetings Completed Successfully ✅

Meeting 1:

  • ✅ 36 minutes 37 seconds of recording
  • ✅ Clean stop via StopEgress API (user action)
  • ✅ Successfully converted to MP3
  • ✅ Uploaded to Vercel Blob
  • ✅ Database updated with audio URL

Meeting 2:

  • ✅ 9 seconds of recording
  • ✅ Clean stop via StopEgress API (user action)
  • ✅ Successfully converted to MP3
  • ✅ Uploaded to Vercel Blob
  • ✅ Database updated with audio URL

3. Different LiveKit Egress IDs ✅

  • Meeting 1: EG_5HnBcxZK8hHV
  • Meeting 2: EG_VEGAkU29oGkn

Each meeting had its own independent egress session - no sharing or collision possible.

4. Different Participant Names

  • Meeting 1: Simran
  • Meeting 2: Host

Suggests user may have used different profiles or names for each tab.


Why No Frontend Logs for Meeting 1?

The Mystery Solved: Meeting 1's creation and recording activity (6:08-6:44 PM IST) is NOT in the frontend Vercel logs because:

  1. Frontend logs only capture API calls to /api routes
  2. LiveKit recording happens entirely on the backend (streaming-backend service)
  3. Meeting 1's recording used LiveKit WebSocket connections, not HTTP API calls
  4. Frontend only calls APIs when:
    • Creating meeting (/api/meetings/create) - likely not logged or filtered
    • Updating meeting (/api/meetings/update) - happened during post-processing at 13:15:39
    • Viewing meeting (/api/meetings/get) - first log at 13:46:53 (21 minutes later)

The /api/meetings/get calls at 13:46:53 UTC (7:16 PM IST) were when the user viewed Meeting 1 after it had already finished recording.


Corrected User Statement

User said: "One of the meetings started around ~6:08 PM IST 11th Nov. Ended at 6:44 PM IST due to start of another meeting on a different tab by the same user."

What actually happened:

  • ✅ Meeting 1 started at 6:08 PM IST - CORRECT
  • ✅ Meeting 1 ended at 6:44 PM IST - CORRECT
  • ❌ "Due to start of another meeting" - INCORRECT
    • Meeting 2 started at 6:54 PM (10 minutes later)
    • Meeting 1 ended because user clicked "End Recording" (StopEgress API)
    • No causal relationship between the two meetings

Likely what happened:

  1. User recorded Meeting 1 for 36 minutes
  2. User manually stopped Meeting 1 at 6:44 PM
  3. User waited for Meeting 1 to process (~1 minute)
  4. User opened new tab and started Meeting 2 at 6:54 PM
  5. User immediately stopped Meeting 2 after 9 seconds (test or accidental start)

Why the Confusion?

The user may have thought Meeting 2 caused Meeting 1 to end because:

  1. Temporal proximity: Both happened on the same day, close in time
  2. Multiple tabs: User had both tabs open, creating mental association
  3. Missing frontend logs: Meeting 1's recording activity not visible in Vercel logs, making it seem "ghost"
  4. UI state confusion: Frontend UI may have shown stale "recording" state after Meeting 1 ended

Recommendations

1. Add Comprehensive Frontend Logging

Problem: LiveKit recording activity doesn't show in Vercel logs

Solution:

// Add telemetry events for LiveKit state changes
telemetryService.track('recording_started', {
  meetingId,
  egressId,
  participantName,
  timestamp: Date.now()
});

telemetryService.track('recording_stopped', {
  meetingId,
  egressId,
  reason: 'user_action', // or 'error', 'timeout', etc.
  duration: recordingDuration,
  timestamp: Date.now()
});

2. Cross-Tab Detection & Warning

Problem: User can start second recording in different tab

Solution:

  • Check localStorage for active recording before starting new one
  • Show modal: "Recording already active in another tab. Stop that recording first?"
  • Add StorageEvent listener to detect cross-tab changes

3. Clear UI State on Recording End

Problem: UI may show stale "recording" state

Solution:

  • Listen for LiveKit egress completion events
  • Update UI immediately when egress ends
  • Add polling fallback to check egress status every 5 seconds

4. Better Error Messages

Problem: User doesn't know why things happen

Solution:

  • Show clear messages: "Recording stopped successfully"
  • Add notification: "Processing recording... This may take a few minutes"
  • Display upload progress from SSE events

Conclusion

No localStorage collision occurred. No dual-recording conflict occurred. Both meetings were independent, sequential operations that completed successfully.

The original RCA (https://gist.github.com/ChakshuGautam/ab4dbd8f04f464e545dceeb2bbc4a901) was based on incorrect assumptions due to missing frontend logs. The LiveKit egress and streaming backend logs prove the meetings were completely separate.

Root Cause of Confusion: Missing frontend logs for LiveKit recording activity made Meeting 1's recording session invisible in Vercel logs, leading to false assumption of collision.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment