Skip to content

V2 Flux keepalive mechanism unclear - connections timeout after ~20-30s silence #649

@Shahid-Mo

Description

@Shahid-Mo

Summary

I'm experiencing connection timeouts with V2 Flux (listen.v2.connect) after 20-30 seconds of silence in a production voice AI application. I've tried multiple approaches based on existing documentation and GitHub issues, but haven't found a working solution. This issue documents my attempts and requests clarification on the recommended keepalive approach for V2 Flux.

What happened?

Actual:

  • V2 Flux WebSocket connection closes after ~20-30 seconds of silence with keepalive ping timeout error
  • Attempted JSON KeepAlive messages ({"type": "KeepAlive"}) → connection immediately dies with error 1005
  • Attempted WebSocket protocol pings (connection._websocket.ping()) every 10s → still times out after 20-30s
  • Attempted DeepgramClientOptions(options={"keepalive": "true"}) → ImportError (doesn't exist in SDK v5)
  • Attempted control messages from PR feat: mention keep alive in migration guide #594 (ListenV1ControlMessage) → ModuleNotFoundError (deepgram.extensions doesn't exist)
  • No documented keepalive mechanism for V2 Flux in docs or migration guides

Expected:

  • Connection should stay alive during natural conversation pauses (60+ seconds)
  • Clear documentation on how to implement keepalive for V2 Flux connections
  • OR documentation stating V2 Flux doesn't support keepalive if that's the case

Context:
V2 Flux is perfect for conversational AI with automatic turn detection, but real conversations have natural pauses (users thinking, reading, distracted). A ~20-30s timeout makes multi-turn applications fragile. The Audio Keep Alive docs and PR #594 migration guide only cover V1, leaving V2 Flux users without guidance.

Steps to reproduce

  1. Install deepgram-sdk==5.3.1
  2. Create a V2 Flux WebSocket connection using client.listen.v2.connect(model="flux-general-en")
  3. Send some audio, receive transcription (works fine)
  4. Wait 30 seconds without sending any audio (simulating user pause)
  5. Attempt to send audio again
  6. Observe ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout

Attempted workarounds (all failed):

Workaround 1: JSON KeepAlive

  • Send await connection._send({"type": "KeepAlive"}) every 10s
  • Result: Connection immediately closes with error 1005

Workaround 2: WebSocket pings

  • Send await connection._websocket.ping() every 10s
  • Result: Pings execute successfully but connection still times out after ~20-30s

Workaround 3: DeepgramClientOptions config

  • Use DeepgramClientOptions(options={"keepalive": "true"})
  • Result: ImportError - class doesn't exist in v5

Workaround 4: Control messages

  • Import from deepgram.extensions.types.sockets import ListenV1ControlMessage
  • Result: ModuleNotFoundError - module doesn't exist in SDK

Minimal code sample

import asyncio
from deepgram import AsyncDeepgramClient

async def test_timeout():
    client = AsyncDeepgramClient(api_key="YOUR_KEY")

    async with client.listen.v2.connect(
        model="flux-general-en",
        encoding="linear16",
        sample_rate=16000,
    ) as connection:
        print("Connected to Flux")

        # Simulate user asking a question and getting response
        # (works fine)
        audio_chunk = b'\x00' * 320  # 20ms of silence
        await connection.send_media(audio_chunk)
        await asyncio.sleep(2)  # Wait for response

        # Simulate user pausing to think (natural conversation)
        print("User pausing for 30 seconds...")
        await asyncio.sleep(30)

        # Try to send audio after pause
        print("Attempting to send audio after pause...")
        try:
            await connection.send_media(audio_chunk)
            print("✓ Audio sent successfully")
        except Exception as e:
            print(f"✗ Failed to send audio: {e}")
            # ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout

asyncio.run(test_timeout())

Logs / traceback

2026-01-23 19:27:57 - INFO - ✅ Connected to Deepgram Flux
2026-01-23 19:28:00 - INFO - ✓ STT final: 'Capital of Australia.'
2026-01-23 19:28:04 - INFO - ✓ Turn complete - back to listening
2026-01-23 19:28:07 - INFO - 💓 Sent WebSocket ping to STT
2026-01-23 19:28:17 - INFO - 💓 Sent WebSocket ping to STT
2026-01-23 19:28:27 - INFO - 💓 Sent WebSocket ping to STT
2026-01-23 19:28:37 - INFO - 💓 Sent WebSocket ping to STT
2026-01-23 19:28:47 - INFO - 💓 Sent WebSocket ping to STT
2026-01-23 19:28:47 - WARNING - ⚠️ STT connection closed: None
2026-01-23 19:28:57 - ERROR - Future exception was never retrieved
future: <Future finished exception=ConnectionClosedError(None, Close(code=<CloseCode.INTERNAL_ERROR: 1011>, reason='keepalive ping timeout'), None)>
Traceback (most recent call last):
  File "/Users/shahid/dev/Projects/voice_ai/.venv/lib/python3.12/site-packages/websockets/legacy/protocol.py", line 1276, in close_connection
    await self.transfer_data_task
  File "/Users/shahid/dev/Projects/voice_ai/.venv/lib/python3.12/site-packages/websockets/legacy/protocol.py", line 951, in transfer_data
    await asyncio.shield(self._put_message_waiter)
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

websockets.exceptions.ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received

Error in Twilio WebSocket: sent 1011 (internal error) keepalive ping timeout; no close frame received
Traceback (most recent call last):
  [... same as above ...]
  File "/Users/shahid/dev/Projects/voice_ai/src/voice_ai/services/voice_session.py", line 186, in handle_audio_chunk
    await self.stt_connection.send_media(pcm_chunk)
  File "/Users/shahid/dev/Projects/voice_ai/.venv/lib/python3.12/site-packages/deepgram/listen/v2/socket_client.py", line 59, in send_media
    await self._send(message)
  File "/Users/shahid/dev/Projects/voice_ai/.venv/lib/python3.12/site-packages/deepgram/listen/v2/socket_client.py", line 82, in _send
    await self._websocket.send(data)
  File "/Users/shahid/dev/Projects/voice_ai/.venv/lib/python3.12/site-packages/websockets/legacy/protocol.py", line 618, in send
    await self.ensure_open()
  File "/Users/shahid/dev/Projects/voice_ai/.venv/lib/python3.12/site-packages/websockets/legacy/protocol.py", line 925, in ensure_open
    raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received

Transport

WebSocket

API endpoint / path

wss://api.deepgram.com/v2/listen

Model(s) used

flux-general-en

How often?

Always

Is this a regression?

  • Yes, it worked in an earlier version

Last working SDK version (if known)

No response

SDK version

5.3.1

Python version

3.12

Install method

uv

OS

macOS (Apple Silicon)

Environment details

- FastAPI application with async WebSocket handlers
- Twilio Media Streams integration (phone call audio)
- Async architecture using AsyncDeepgramClient
- Real-time bidirectional audio streaming (Twilio μ-law 8kHz ↔ PCM 16kHz)

Link to minimal repro (optional)

No response

Session ID (optional)

No response

Project ID (optional)

No response

Request ID (optional)

No response

Code of Conduct

  • I agree to follow this project’s Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions