STT streaming session limits: the caps, the failure modes, the reconnect loop
A live speech-to-text stream never runs forever. One major vendor ends streams at five minutes. Another allows eight hours per connection. Most publish the number nowhere a buyer would look. This page puts every published streaming session cap in one dated table, sorts the ways a stream dies into four shapes, and shows the reconnect loop that carries hours of live audio past any cap.
The batch side of the same problem is its own guide. File caps, chunk cutting, and speed math live there: transcribe long audio files: limits, chunking, speed math. This page owns the live side. That means the session timer, the failure shape, and the client loop.
The wall you cannot see
Batch transcription fails loudly. You send a file that is too large. The service refuses it with an error and a status code. Streaming fails quietly. A stream that has been healthy for an hour goes silent. Or the socket drops. Or the service closes the connection without a word. These outages look like network trouble. Often they are a timer.
The numbers exist. They sit in quota tables, FAQ pages, and error-code lists rather than on feature pages. Every row in the table below was read from that vendor's own documentation on 28 October 2026. Where a vendor publishes no cap, the table says so, with the check date. An undocumented cap is still a cap. It is one you discover in production instead of in planning.
Caps also move. One vendor's FAQ page said four hours per streaming connection in a September 2026 read by this platform's team. The same page says eight hours today. That change landed inside seven weeks. Treat every number here as a dated read. Re-check the two or three rows that matter to you on the day a design decision rides on them.
The table: every published streaming session cap
| Provider | Session cap, read 2026-10-28 | What happens at the cap | Idle rule | Source |
|---|---|---|---|---|
| Google Cloud STT v2 | 5 minutes per stream | the stream is ended; the documented workaround is a client-side restart loop | audio must arrive at near real-time rate, or a 400 audio-timeout error fires | quotas page |
| OpenAI | 60 minutes per Realtime session; no cap published on the plain transcription endpoints | the session ends at the limit; open a new one to continue | no separate idle rule published | conversations guide |
| Azure Speech | none published for general streaming; 240 minutes per session on the real-time diarization variant | the diarization session ends at 240 minutes | no idle rule on the quotas page | quotas page |
| Amazon Transcribe | 8 hours per streaming connection | a maximum-session-duration error; you start a new session to continue | SDK threads describe a roughly 15-second no-audio timeout | FAQ |
| AssemblyAI | auto-closes at 3 hours | clean close; an unclosed session is billed for the full open duration | no separate idle rule published | streaming docs |
| Deepgram | no total-session cap published | the connection closes 10 seconds after audio and keep-alive messages both stop, with a named error code | a keep-alive message every 3 to 5 seconds holds it open | keep-alive docs |
| Gladia | 3 hours per WebSocket session | the session is terminated at the limit; their docs say to open a new session before reaching it | no separate idle rule published | limits page |
| Speechmatics | sessions auto-end at 48 hours | auto-end; their docs suggest connecting the next session a few seconds early for a seamless switch | 1 hour with no audio, or 3 minutes with no audio and no pings | realtime limits |
| Soniox | 300 minutes per session, fixed | the session ends and you open a new one; the cap is not increasable | 10 concurrent streams is the published companion limit | limits page |
| This platform | a streaming request ends at a 230-second cap | a named terminal event, then a clean close; long audio rides successive requests by design | strict input form, 16 kHz 16-bit mono PCM or WAV; a mid-stream fault emits a named retryable error event, never a silent drop | the platform contract, dated in the section below |
Three honest readings of the table. First, the spread is enormous. Five minutes at Google and eight hours at Amazon are both sold as streaming speech to text. That is a spread of nearly one hundred times. A captioning app and a full-shift call monitor are different products, and the table is why.
Second, the session column is where documentation goes to die. Two of the ten rows publish no total cap at all. One more publishes a cap only for a special variant. The numbers that do exist sit on quota, FAQ, and error pages. No vendor puts the session cap on its product page, and no ranking page tracks it. The pages that do rank track price and accuracy. A buyer comparing on price and accuracy alone can pick a provider whose cap breaks the product on day one.
Third, the idle column is a different wall. Deepgram closes in 10 seconds without audio. Amazon threads describe about 15 seconds. Google requires audio near real time, or it errors out. None of these are session caps, and fixing them with a restart loop fixes the wrong thing. Keep-alive messages fix idle walls. Restart loops fix age walls. Most production systems need both.
Four ways a stream dies
The failure taxonomy. Every silent 3 a.m. page about streaming speech traces to one of four shapes.
The idle kill. Audio stops, and the service closes after a short window. Deepgram documents 10 seconds. Amazon SDK threads describe about 15. The stream was healthy. It just had nothing to say. The fix is keep-alive traffic or a silence floor, never a reconnect.
The silent drop. The connection closes with no error event. Client logs show nothing until the socket is already gone. One widely used SDK has a public thread on exactly this. The connection closes abruptly. No error fires before the close. Microsoft support threads describe the same shape on Azure speech sockets as an abnormal close. This is the worst class to debug, because there is nothing to debug. The fix is a watchdog: if no events have arrived for N seconds, assume death and reconnect.
The clean auto-close. The service ends the session at a documented timer. AssemblyAI closes at 3 hours. Gladia ends at 3 hours. Speechmatics ends at 48. Soniox ends at 300 minutes. This is the best class, because it is planned. Your client knows the timer, reconnects on schedule, and the user never notices. The only trap is billing, covered below.
The hard terminate. The connection is killed mid-stream with no close frame. This platform's own aging tests saw exactly this shape. The long-lived connection behind the streaming face ended between 222 and 248 seconds. No close frame arrived. Proxies and load balancers do the same thing at 30, 50, or 60 minutes. A public app-hosting forum documents silent 50-minute kills of WebSocket apps. Sometimes the wall is not the vendor at all. It is the hop in front of the vendor.
The reconnect loop that carries live audio
Three patterns cover the field. All three predate this page by years. Streaming vendors that cap at five minutes force the pattern on day one.
Restart before the cap. Google's own endless-streaming tutorial is the reference sample. Their code sets a restart interval of four minutes, safely under the five-minute stream cap. At the interval, it closes the stream, opens a new one, and re-sends the audio that arrived during the swap. Timestamps are bridged with a restart counter. The transcript then reads as one continuous session. (endless streaming tutorial)
Overlap the old and new sessions. Speechmatics suggests connecting the new session a few seconds before the old one ends. Gladia says plainly to start the new session before reaching the limit. Overlap trades a few seconds of double cost for a gapless transcript. Under per-audio metering the double cost is small. Under open-connection metering, plan it.
Treat the named terminal as routine. The best outcome is a close with a name. This platform's streaming face ends a long request at its 230-second cap with a named terminal event. A clean end marker follows. The client reconnects on the event, not on an error. No watchdog guess. No dead air while you decide whether the silence is a failure.
The four client habits, whatever the provider. Buffer incoming audio so nothing is lost during a session swap. Resume from the last final transcript, not from the last partial. Bridge timestamps across sessions with a counter. Log the close code on every disconnect. The code names the cause. Named codes are timers. Abnormal codes are kills. No code at all is a proxy.
What a session boundary costs
Session caps are free. Session boundaries can be expensive. The billing shape decides.
Two shapes exist. Under audio metering, you pay for the audio your sessions report. Silence does not bill, and a meeting split across ten sessions costs the same as one. Under open-connection metering, you pay for the time the socket stays open. AssemblyAI documents the second shape in plain words (docs read 28 October 2026). Streaming is billed on the total duration the connection stays open, not on the audio sent (streaming docs). Their own end event carries both numbers, audio duration and session duration. The gap is visible per session.
The trap is the abandoned session. An open-connection session that nobody closes does not stop costing at the end of the meeting. It costs until the cap. AssemblyAI auto-closes unclosed sessions at 3 hours and bills the full duration. A reconnect loop that leaks old sessions can multiply a bill. Close what you open, on every provider.
This platform's rates render from the catalog at build time, never typed by hand.
| Model | Context | $/1M in | $/1M out | $/1M cached |
|---|---|---|---|---|
| Qwen | ||||
| qwen3.8-27b | 262K | $0.35 | $2.55 | $0.105 |
| qwen3.6-35b | 131K | $0.11 | $0.8 | $0.044 |
| Minimax | ||||
| minimax-m2.7 | 197K | $0.24 | $0.95 | $0.072 |
| Muse | ||||
| muse-glimmer-30b | 131K | $0.28 | $1.2 | $0.084 |
| Ornith | ||||
| ornith-1.5-35b | 100K | $0.35 | $2.55 | $0.105 |
| ornith-1.5-9b | 100K | $0.1 | $0.3 | $0.03 |
| Glm | ||||
| glm-5.3-flash | 1049K | $0.11 | $0.35 | $0.033 |
| Deepseek | ||||
| deepseek-v4-flash-0731 | 1311K | $0.15 | $0.42 | $0.045 |
| Gemma | ||||
| gemma-4-31b-it | 262K | $0.22 | $0.49 | $0.066 |
| Deepseek | ||||
| deepseek-v4-pro | 1000K | $1.13 | $2.21 | $0.339 |
| deepseek-v4.1-flash | 1000K | $0.19 | $0.71 | $0.06 |
| deepseek-v4.1-flash-1017 | 1049K | $0.16 | $0.65 | $0.003 |
| Glm | ||||
| glm-5.3 | 1000K | $1.32 | $4.25 | $0.4 |
| Flux | ||||
| flux-1-schnell | — | $0.003/image | ||
| flux-pro-1.1 | — | $0.04/image | ||
| Chatterbox | ||||
| chatterbox-tts | — | $25/1M chars | ||
| Kokoro | ||||
| kokoro-tts | — | $15/1M chars | ||
| pocket-tts | — | $16/1M chars | ||
| Audio | ||||
| audio8-tts | — | $8/1M chars | ||
| Hayamimi | ||||
| hayamimi-stt | — | $0.6/audio-hr | ||
| Bge | ||||
| bge-m3 | — | $0.05/1M tokens | ||
| bge-reranker-v2-m3 | — | $1.5/1k searches | ||
| Ocr | ||||
| ocr-print | — | $1/1k pages | ||
| ocr-archival | — | $3/1k pages | ||
| Whisper | ||||
| whisper | — | $0.12/audio-hr | ||
| Iab | ||||
| iab-2x | — | $0.7/1k pages | ||
| iab-3x | — | $0.7/1k pages | ||
| Gliner | ||||
| gliner-extract | — | $0.9/1k searches | ||
| Jev | ||||
| jev-fast | 1K | $0.03 | $0 | — |
| jev-causal | 1K | $0.03 | $0 | — |
| jev-batch | 1K | $0.03 | $0 | — |
| Wemm | ||||
| wemm-embed | — | $0.09/1M tokens | ||
| Molmo | ||||
| molmo2-er | 8K | $1 | $5 | $0.5 |
| Cosmos | ||||
| cosmos-reason2-2b | 4K | $0.1 | $0.4 | $0.05 |
| Sam | ||||
| sam2.1-base | — | $0.02/image | ||
| Da | ||||
| da3-small | — | $0.05/image | ||
| Smolvla | ||||
| smolvla | — | $0.001/call | ||
| Openvla | ||||
| openvla-oft | — | $0.006/call | ||
| Act | ||||
| act | — | $0.001/call | ||
cost of live audio = H x P
H = audio hours your sessions reported, summed across all sessions
P = the per-audio-hour rate from the fence above
One line: the session count never enters the formula. H is the same whether the audio crossed one session or fifty. The metering law behind it is short. The streaming face sums audio seconds from final events, never wall-clock. Silence does not bill. Spending draws down a prepaid wallet, so a client bug's worst case is the balance loaded, not an open-ended bill. The guard patterns for long jobs are their own guide: how to avoid API bill shock.
Streaming speech to text on this platform
The streaming face is the transcription endpoint with stream=true. The response becomes server-sent events. Draft text arrives as partial events. Each finished segment arrives as a final event. One refine event per session re-emits the first final with the detected language code. The stream opens with a keep-alive ping line and ends with a terminal done marker. There is no language field to send. Detection is automatic on this face.
The input law is strict. Audio must be raw PCM or WAV at 16 kHz, 16-bit, mono. Anything else is refused with a 400 before work starts. Bodies are capped at 25 MiB. Convert first, then send.
The cap law is named, not silent. A streaming request ends at a 230-second cap with a named terminal event. The connection behind the request closes at roughly 240 seconds of age, confirmed with the host on 2026-10-27. The platform's own test sessions ended between 222 and 248 seconds. The cap is the design, not a defect. Long live audio rides successive requests. The client treats a boundary as a normal event. A mid-stream fault emits a named retryable error event and a clean end, never a bare drop. The batch variant of the same endpoint takes finished files. It keeps its own roughly 240-second effective per-request ceiling. It is the right face when nothing is waiting on the words. The chunking client for that face is in the long audio guide.
As of 2026-10-28 the platform's speech-to-text lanes are hayamimi-stt and whisper. Hayamimi-stt is the streaming lane the numbers above describe. Whisper is the batch lane. Both meter per audio second. The cost side of the whisper lane, with every named rate dated, is the whisper cost calculator page.
A first streaming call with the reconnect habit built in:
# pip install requests
# each piece: 16 kHz 16-bit mono WAV, under 25 MiB (ffmpeg -i in.wav
# -ar 16000 -ac 1 -sample_fmt s16 out.wav)
import json, os
import requests
URL = os.environ["IRONSTRATUM_BASE_URL"] + "/v1/audio/transcriptions"
HDR = {"Authorization": "Bearer " + os.environ["IRONSTRATUM_API_KEY"]}
def stream_piece(path):
"""One streaming request. The named terminal ends the session at
the 230 s cap; the driver simply opens the next piece."""
with open(path, "rb") as audio, requests.post(
URL, headers=HDR,
files={"file": audio},
data={"model": "hayamimi-stt", "stream": "true"},
stream=True, timeout=300,
) as resp:
resp.raise_for_status()
for line in resp.iter_lines():
if not line.startswith(b"data: "):
continue # keep-alive pings and blanks
payload = line[6:]
if payload == b"[DONE]":
return "ended" # clean end: next piece
event = json.loads(payload)
kind = event.get("type")
if kind == "transcription.final":
print("FINAL:", event["text"])
elif kind == "transcription.refine":
print("language:", event["lang"])
elif kind == "error":
print("named error:", event.get("code"),
"retryable:", event.get("retryable"))
return event.get("code") # reconnect on a name, not a guess
for piece in ("shift-000.wav", "shift-001.wav", "shift-002.wav"):
print(piece, "->", stream_piece(piece))
Contract facts that save an afternoon. The model string is the catalog alias. Each request meters its own audio seconds from its final events. Unknown form fields are a 400. The speaker-labeled streaming lane is a separate question. Its WebSocket face, and why it is not on this endpoint today, is covered in the real-time speaker diarization guide.
Decision rules
| Your situation | The rule |
|---|---|
| Live captions under 5 minutes per utterance | Any provider works. Cap the session yourself and idle walls never bite. |
| Meetings or shifts of hours | Pick a row with a documented cap you can live with, and ship the restart loop before the first long session. |
| Provider publishes no cap | Budget engineering time for the silent-drop class: watchdog, buffered audio, reconnect on suspicion. |
| Streams die with no error code | Assume a timer first, a proxy second. Log close codes and durations for one week, then match them against the table. |
| Audio arrives in bursts with long gaps | Fix the idle wall with keep-alive traffic. A restart loop will not help. |
| Billing is per open connection | Close every session the moment it ends. An abandoned session bills until its cap. |
The reconnect loop is generic client craft. It is the difference between a streaming demo and a streaming product. Rates for every lane sit on the pricing page. To run it on real audio, sign up. Create a key, load a small wallet, and point the snippet at your first hour.
Frequently asked questions
How long can a streaming transcription session run?
It depends on the provider, by a factor of nearly one hundred. Google Cloud STT v2 caps a stream at 5 minutes. OpenAI caps a Realtime session at 60 minutes. Amazon Transcribe allows up to 8 hours per streaming connection as of the 28 October 2026 FAQ read. Speechmatics auto-ends at 48 hours. Soniox fixes 300 minutes. Two providers in the table publish no total cap at all. The table above carries every number with its read date and source link.
What happens when a streaming session hits its limit?
One of four things, and the difference matters. A clean auto-close ends the session with a notice, as at AssemblyAI, Gladia, and Speechmatics. A named terminal event ends this platform's streaming requests at the 230-second cap. A hard terminate kills the connection with no close frame. This platform's own aging tests recorded 222 to 248 seconds on the connection behind the stream. A silent drop closes with no error at all, the shape reported in public threads on major vendors' own SDKs. Know which of the four your provider does, because the client handling differs for each.
Why does my speech-to-text WebSocket drop with no error?
Three usual causes. A session timer expired, and the vendor closes quietly rather than announcing it. An idle timeout fired because no audio or keep-alive arrived, with windows as short as 10 seconds at Deepgram. Or the drop is not the vendor at all. Proxies and load balancers kill long-lived sockets at 30, 50, or 60 minutes. App-hosting forums document exactly that shape. Log the close code and the session age at every disconnect. The pattern names the cause.
Do any providers bill for the time a session stays open?
Yes. AssemblyAI bills streaming on the total time the connection stays open, not on the audio sent. An unclosed session there auto-closes at 3 hours. It is billed for the full duration. That is a different contract from audio-second metering, where silence does not bill and a session split costs nothing extra. Ask two questions before committing: what does a minute of silence cost, and what does an abandoned session cost.
How do I keep a live transcript running past the cap?
With a restart loop, planned before the first long session. Restart the session just under the cap, as Google's own sample does at four minutes under a five-minute limit. Buffer incoming audio during the swap and re-send whatever arrived while no session was open. Resume from the last final transcript, not the last draft. Bridge timestamps with a session counter so the merged transcript reads continuously. Where the provider offers overlap, connect the next session a few seconds before the old one ends.
Is the session cap the same thing as the idle timeout?
No, and confusing them wastes the fix. A session cap is an age limit: the stream dies after N minutes no matter how busy it is. An idle timeout is an activity limit. The stream dies after N seconds of no audio or keep-alive, no matter how young it is. Deepgram's 10-second window and Amazon's roughly 15-second behavior are idle walls. Google's five-minute stream limit and AssemblyAI's three-hour close are age walls. Keep-alive messages fix the first kind. Restart loops fix the second. Long-running production systems carry both.
Does a session cap apply to batch transcription too?
Batch has its own limits, and they are usually larger and better documented. File sizes, durations per request, and content lengths. This page is the live side. The batch side is the long audio guide. It carries every provider's file caps, the chunking client, and the speed math with a measured real-time factor. The batch companion page with the limits table and the silence-aware chunker is long audio transcription limits.
Rates and metering units for every lane sit on the pricing page. To run one live session end to end, sign up. Create a key, load a small wallet, and point the snippet at your longest recording.
Last verified: 2026-10-28