Rate Limits & Concurrency
Murf provides dedicated request capacity based on your plan. Each plan includes specific limits for concurrency and WebSocket connections. As your application scales, you can upgrade your plan to increase capacity.
Every Falcon 2.1 streaming response also tells you which region served it, that region’s limit, and how many slots you’re using right now. See Check your usage.
Limits by plan
Below is a summary of the concurrent request limits for each plan:
Speech to Text limits are separate from Text to Speech limits. Usage of one doesn’t count against the other.
How concurrency is counted
Concurrency for Streaming (Falcon 2.1)
Our TTS API supports streaming via both HTTP and WebSocket connections. Concurrency for streaming is the number of requests or contexts active at the same time, counted per region:
- HTTP streaming: each in-flight request uses one slot until its audio finishes.
- WebSocket streaming: each active
context_iduses one slot until the context ends. More text sent to the samecontext_iddoesn’t use another slot, because requests to the same context are processed in order. Text sent without acontext_idgoes to the default context, which also counts as one.
Usage in one region doesn’t count against another. If you go over the limit, see When you hit the limit.
Concurrency for Synthesize (Gen 2)
Concurrency refers to the maximum number of generation requests that can be processed simultaneously. For all non-streaming endpoints, this is defined as the number of active requests at any given time.
WebSocket Limits
Two limits apply to WebSocket usage. They are counted separately: open connections do not consume or increase streaming concurrency.
An open socket does not consume concurrency. Concurrency is consumed only while audio is being generated on that socket.
The number of sessions that can generate audio at the same time is capped by your streaming concurrency—not by your connection count. The larger connection allowance lets you keep sockets open and avoid a new handshake for every call; it does not increase throughput.
- A WebSocket connection closes automatically after 3 minutes of inactivity.
- If you attempt to open a new WebSocket connection after exceeding your limit, an error will be returned.
Concurrency for Speech to Text
Speech to Text (Beta) streams over a WebSocket. Finch-Indic connects to wss://in.api.murf.ai/v1/transcription/stream-input. Finch-Global connects to wss://us-east.api.murf.ai/v1/transcription/stream-input. Concurrency is the number of Speech to Text connections open at the same time for your API key. Unlike Text to Speech, each open connection uses one slot until it closes, whether or not you’re sending audio.
The WebSocket limits above apply to Text to Speech only. If you’re already at your Speech to Text limit, a new connection is closed with code 4004. See Speech to Text: close code 4004.
Regions and the Global URL
Falcon 2.1 limits apply per region. Responses name the serving region with its cloud region code:
global.api.murf.ai sends each request to the nearest region, so your limit depends on where the request came from. A request from Bangalore lands in ap-south-1 (India, limit 2), not us-east-2 (limit 5). Responses always name the region that actually served the request, never global. To use a specific region’s limit, call that region’s host directly.
Check your usage
You get your usage in the responses you already receive. There’s no extra endpoint to call.
HTTP streaming headers
Every successful response and every 429 from POST /v1/speech/stream carries these headers. They arrive before the first audio byte.
Browser JavaScript can read these headers too; they’re listed in Access-Control-Expose-Headers. Don’t put your API key in browser code; see API key safety.
WebSocket messages
On every final message. When a context finishes, its final message carries a concurrency object. used counts the active contexts in that region, including the one that just finished. Clients that ignore unknown fields need no change.
At the start of each context (opt-in). Add include_usage=true to the connection URL to also get a session_info message when Murf starts processing each context, before its first audio chunk:
session_info has no audio field, so it’s off by default: clients that assume every non-final message carries audio keep working. Turn it on only when your message handler checks for it:
On connect. The handshake response carries the same four X-Murf-* headers. used is the number of contexts you already have active in that region; opening a connection doesn’t use a slot. Server-side clients can read these headers. Browsers don’t let JavaScript read handshake headers, so browser apps should use session_info or final.
Python SDK support for reading usage is coming soon. Until then, use the HTTP or WebSocket examples above.
When you hit the limit
HTTP streaming: 429
A request over the limit gets HTTP 429 with the same four headers, a Retry-After header in seconds, and this body:
Branch on error, not on the message text. To handle it:
- Wait
Retry-Afterseconds, then retry. Add jitter if many workers retry at once. - Cap your in-flight requests at the
limitfor the region inX-Murf-Region. - If you hit 429 often, call
us-east.api.murf.aidirectly (it has the highest default limit), or contact sales for a higher limit.
WebSockets: over the limit
If a new context_id would go over the limit, you get an ACTIVE_CONTEXT_LIMIT_EXCEEDED error frame for that context:
The connection is then closed with code 4029, which stops every context
on it, including ones that were within the limit. Keep the number of active
contexts below limit, close finished turns with {"end": true}, and handle
close code 4029 by reconnecting.
A context’s slot is freed shortly after its final message, not at the same moment. If you run at your limit, wait for final plus a short margin before starting the next context.
See Errors & Warnings for every error and close code.
Speech to Text: close code 4004
If you open a new Speech to Text connection while you’re at your limit, the server sends an Error message and closes the connection with code 4004. To handle it:
- Retry with exponential backoff.
- Keep one connection per call, and use
Finalizebetween turns instead of reconnecting. - On pay as you go, contact us to raise your limit from 20 to up to 150. For more than 150, ask about Enterprise.
See Speech to Text errors for every close code.
FAQs
Why does my limit change between requests on the Global URL?
The Global URL routes each request to the nearest region, and limits are
per region. Check X-Murf-Region to see which region served a request.
To use one region’s limit consistently, call that region’s host directly.
Does an open WebSocket connection use a concurrency slot?
No. Only active contexts use slots. Connections have their own, larger allowance; see WebSocket Limits.
Can I check my usage without making a request?
Not yet. Usage comes back on the requests you make.
Why did my WebSocket close with code 4029?
A new context went over your concurrency limit in that region. The error frame before the close names the region and limit. Reconnect, and keep fewer contexts active at once.
Why These Limits Matter
The limits are designed to maintain system performance and ensure a consistent experience for all users. By adhering to the limits and following best practices, you can integrate the Murf API smoothly and efficiently into your applications. If you have additional questions or need guidance on managing API limits, please drop a message in our discord channel or contact our support team.