How concurrency works
Each workspace may have a fixed number of TTS generations running concurrently. When a request starts it takes a slot; when it finishes it releases the slot. If all slots are busy, the next request is rejected immediately with429 rather than being queued.
The limit is scoped to your workspace and driven by your plan tier.
Limits by plan
| Plan | Concurrent TTS requests |
|---|---|
| Free | 2 |
| Starter | 3 |
| Startup | 10 |
| Scale | 25 |
These are the current defaults and can change as plans evolve. Check your plan in the dashboard for the value that applies to your workspace.
The 429 response
When you exceed your concurrency limit:403 instead:
Handling limits
The API does not queue requests or send aRetry-After header, a 429 is an immediate rejection. Handle it on the client:
- Cap your in-flight requests to your plan’s concurrency limit so you rarely hit
429in the first place. - Retry with exponential backoff and jitter when you do, e.g. 0.5s, 1s, 2s, 4s with random jitter.
- Use a worker pool sized to your limit rather than firing all requests at once.
Python