Latency

Simba 3.2 first byte measured 56 ms p50 and 102 ms p90 on our production US East streaming path, 15 Sep 2026. What adds to it on your side, and how to measure your own.

On 15 Sep 2026, SpeechifyAI’s simba-3.2 model returned its first audio byte in 56 ms at the median (p50) and 102 ms at p90 on our production streaming path in US East. That is the part of the wait spent inside our API. What a listener hears also depends on the network between you and US East, how your client connects, the audio format and your player. This page shows how each of those adds up, and how to measure it from where your code runs.

Measured numbers

MetricValueWhat it measuresMeasuredPath
First byte, p5056 mssimba-3.2: from our API admitting the request to writing its first audio byte15 Sep 2026Production POST /v1/audio/stream, US East
First byte, p90102 msSame metric; 9 in 10 requests were at or under this15 Sep 2026Production POST /v1/audio/stream, US East
First byte, p50161 msSame metric on simba-3.015 Sep 2026Production POST /v1/audio/stream, US East

These are measured percentiles from production traffic, not a guarantee. They are not time to audible audio, and they do not include the network between you and US East.

First byte, first audible audio, total generation time

TermDefinition
Time to first byteFrom sending the request to receiving the first byte of audio. The numbers above are the part of it spent inside our API.
Time to first audible audioTime to first byte, plus any silence at the start of the audio, plus the time your decoder and player take before sound comes out.
Total generation timeFrom sending the request to receiving the last byte of audio. It grows with the length of the text.

Generated speech can begin with a short silence, and its length varies with the voice and the text. On POST /v1/audio/speech, time to first byte and total generation time are the same, because the response is sent once the whole clip exists.

How we measure

  • What is timed. Every production request to POST /v1/audio/stream records, inside our API, the time from admitting the request (after authentication and rate limits) to writing the first audio byte to the response.
  • Which requests. Successful streaming requests from real customer traffic, not a synthetic test, split by model. The figures above were read from that traffic on 15 Sep 2026.
  • Which statistic. Percentiles, not averages. p50 is the median request; p90 is the request slower than 9 in 10. A few slow outliers move an average, not a median.
  • Where. Our US East serving path, which served every request to api.speechify.ai in September 2026. The clock stops when the first byte leaves our API, so the network between you and US East, the handshakes of a new connection, silence at the start of the audio and your player’s buffer are all outside it.
  • Cross-checked from outside. We also time requests from the client side: a probe sends varied text to the streaming endpoint from a machine in US East and from other locations, timestamps DNS, TCP, TLS and every chunk, and finds the first audible 10 ms window in the decoded audio. The examples below do the same, without the audio analysis.

What adds latency on your side, and how to cut it

FactorEffectWhat to do
Batch instead of streamingPOST /v1/audio/speech responds once the whole clip is generated, so the first audio waits for the last.Use POST /v1/audio/stream for anything played while it generates. Keep the speech endpoint for files you store.
ModelMedian first byte was 56 ms on simba-3.2 and 161 ms on simba-3.0, same path, same day.Set model: "simba-3.2" for English. The API uses simba-3.0 when model is omitted. See Models.
Distance to US EastEvery request pays at least one network round trip to US East. In our September 2026 measurements that round trip was about 35 ms from the central US and about 100 ms from central Europe.If the code that calls the API runs in a cloud, run it in or near US East.
A new connection per requestA DNS lookup and the TCP and TLS handshakes run before the request is sent.Create one HTTP client and reuse it. Open the connection at startup so a user’s first request does not pay for it. HTTP/2 lets concurrent streams share one connection.
Compressed outputMP3, Ogg/Opus and AAC are encoded as the audio is generated and decoded by your player, and decoded MP3 starts with a short encoder delay. audio/pcm at 24 kHz is the model’s native output and needs no encoding step.Use Accept: audio/pcm when you play or process raw samples. Use a compressed format when bandwidth or file size matters more. See Audio formats.
Waiting for the full textSynthesis cannot start before the text arrives. An LLM reply sent in one request waits for the LLM’s last token.Send each complete sentence as soon as it exists and play the streams in order. Split only at sentence ends: splitting inside a sentence changes how it sounds. Text you already have goes in one request, up to 20,000 characters.
Player start-upA player that fills a buffer before it starts adds that buffer to time to first audible audio.Start playback on the first chunk. With PCM, write samples to the audio device as they arrive.

Measure it yourself

Time the first chunk of a streaming response from where your code runs, and read the Server-Timing header on the same response. Its ttfb is our share of that request’s wait, from the request reaching our API to the first audio byte, and model is the model’s own time to first audio. Your first-chunk time minus ttfb is the network and your own stack. ttfb starts slightly earlier than the published figures, so it also counts authentication and rate limiting.

For a fair number:

  • Discard the first request or two. They include opening the connection.
  • Vary the text between requests, as your real traffic does.
  • Send requests one after another. A request beyond your plan’s concurrency limit returns 429, not a slower response.
  • Take at least 20 requests and report p50 and p90, not the average or the single best run.
  • Measure with PCM. With Ogg, the first bytes are header pages, not audio.
# pip install httpx
import os
import re
import statistics
import time
import httpx
# One client for every request, so the connection is reused.
client = httpx.Client(
base_url="https://api.speechify.ai",
headers={"Authorization": f"Bearer {os.environ['SPEECHIFY_API_KEY']}"},
timeout=30.0,
)
def measure(text: str) -> tuple[float, float, str]:
start = time.perf_counter()
first_chunk_ms = None
with client.stream(
"POST",
"/v1/audio/stream",
headers={"Accept": "audio/pcm"},
json={"input": text, "voice_id": "geffen_32", "model": "simba-3.2"},
) as response:
response.raise_for_status()
for _ in response.iter_raw():
if first_chunk_ms is None:
first_chunk_ms = (time.perf_counter() - start) * 1000
total_ms = (time.perf_counter() - start) * 1000
match = re.search(r"ttfb;dur=([\d.]+)", response.headers.get("server-timing", ""))
if first_chunk_ms is None:
first_chunk_ms = total_ms
return first_chunk_ms, total_ms, match.group(1) if match else "n/a"
for n in range(2):
measure(f"Opening the connection, request {n}.") # not counted
first_chunks = []
for n in range(20):
first_chunk_ms, total_ms, server_ttfb = measure(
f"Your order {1000 + n} shipped this morning and arrives on Thursday."
)
first_chunks.append(first_chunk_ms)
print(f"first chunk {first_chunk_ms:.0f} ms, server ttfb {server_ttfb} ms, total {total_ms:.0f} ms")
deciles = statistics.quantiles(first_chunks, n=10)
print(f"first chunk p50 {deciles[4]:.0f} ms, p90 {deciles[8]:.0f} ms")

FAQ

No. It is the median first byte measured on production streaming traffic on 15 Sep 2026, with p90 at 102 ms, not a service-level commitment. The Server-Timing header on each of your own responses reports the same kind of measurement for that request.

Your measurement includes the network between you and US East, the handshakes of any new connection, and, depending on the tool, decoding and playback. Compare your first-chunk time with ttfb in the Server-Timing header: the difference is everything outside our API.

POST /v1/audio/stream with model: "simba-3.2" and Accept: audio/pcm, from a client that reuses its connection and runs near US East. simba-3.2 is English only; use simba-3.0 for the other languages it supports.

On POST /v1/audio/stream, audio starts arriving before the whole input has been synthesized, so send text you already have in one request; total generation time grows with length. On POST /v1/audio/speech, the response waits for the whole clip, so the first audio grows with length.

As of September 2026, every request to api.speechify.ai is served from US East, and the measured numbers on this page are for that path.