-
Notifications
You must be signed in to change notification settings - Fork 120
Description
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 timeouterror - 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.extensionsdoesn'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
- Install
deepgram-sdk==5.3.1 - Create a V2 Flux WebSocket connection using
client.listen.v2.connect(model="flux-general-en") - Send some audio, receive transcription (works fine)
- Wait 30 seconds without sending any audio (simulating user pause)
- Attempt to send audio again
- 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