No benchmark results are published yet
As of , Rexa.ai has published no latency figures, no uptime figures, no answer rates and no customer results. Not lower ones, not preliminary ones — none. The harness described below is written and reproducible, but it has not been run against production for long enough to produce a sample worth quoting.
When a run completes and a second person has checked it, the figures will appear on this page with the date they were measured, the raw data, and the conditions they were measured under. If you are reading this and that has not happened, it has not happened. Any Rexa.ai performance number you find elsewhere did not come from us.
Why we have not published numbers
Two reasons, and neither is that the numbers are bad.
The first is that a latency figure without its conditions is not information. Voice platform latency moves with the caller’s network, the region the client connects from, the model and voice in use, the length of the prompt, and the time of day. A vendor page that says “sub-500 ms” and nothing else has told you the vendor once observed a number, which is not a claim you can act on or check.
The second is arithmetic. The endpoint the harness measures is free and rate limited to roughly 20 rooms per hour, which is exactly why it is safe for anyone to reproduce. It also means a sample large enough to support a p99 takes more than five hours of continuous collection, and a defensible figure needs that repeated across several days. That is a scheduling problem we have not finished solving. It is not a reason to publish a p99 computed from a dozen samples, which is a maximum wearing a percentile’s name.
What the harness measures
It drives POST /v1/rooms/test, the free test-room endpoint documented in the rooms API reference. That endpoint places no credit hold, caps the room lifetime at about 120 seconds and never touches the phone network — so the benchmark costs nothing to run, calls nobody, and can be reproduced by any developer with an API key.
| Metric | Definition | How it is measured |
|---|---|---|
| room_provisioning_ttfb | Request sent to response headers received. | performance.now() delta in the process that issued the POST, taken when fetch resolves its response. |
| room_provisioning_token_issued | Request sent to a usable join token in hand. | Same start point, taken after the response body is fully read and parsed. This is what a browser client waits on before it can begin connecting. |
| room_url_reachable | Request sent to an unauthenticated GET of the returned room URL responding. Opt-in. | A reachability probe of the WebRTC provider edge. It is not an audio measurement and is reported separately for that reason. |
What this benchmark cannot tell you
The harness measures control-plane provisioning. That is a real number and a useful one, but it is a small part of what people mean by “voice latency”, and it would be easy to quote it as though it were the whole thing. It is not.
- Time-to-first-audio
- Timestamping the first inbound audio frame needs a real WebRTC client to join the room and negotiate media. Node has no WebRTC stack in its standard library, and adding a headless browser would destroy the property that makes the harness worth publishing — that anyone can copy one file and re-run it. Until a separate browser-side probe exists, no time-to-first-audio figure appears anywhere on this site.
- Conversational turn latency, and its speech-to-text, model and speech synthesis split
- Nothing in the harness exercises the media path, so it says nothing about how long a spoken turn takes end to end.
- Anything at all about phone calls
- Test rooms never touch a carrier. No number produced here describes PSTN call setup, carrier variance, or codec-induced delay — measuring those means placing real calls to real numbers, which is neither free nor something to do at benchmark volume.
- The platform in isolation
- Every measurement includes the network path from the machine that ran it. Results are only comparable between runs taken from similar locations on similar links, which is why the location and network labels are mandatory inputs rather than optional notes.
Methodology
- Configuration is validated before anything is called. The run refuses to start without an API key, a location label describing where the measuring machine sits, and a label describing its measured network conditions. A latency figure whose measurement point is unknown cannot be compared with anything.
- Warm-up iterations run first and are discarded. The first request to a host pays DNS, TCP and TLS setup that a long-lived client pays once and then amortises; including it measures the handshake rather than the platform.
- Each iteration POSTs an identical body to the free test-room endpoint, timing the response headers and then the fully parsed body containing the join token from the same start point. The prompt is held constant and its SHA-256 is written into the result file, so two runs can be proven comparable.
- Iterations are paced 185 seconds apart. The endpoint is rate limited to roughly 20 rooms per hour per tenant, so 3600 ÷ 20 = 180 seconds is the floor, plus margin for clock skew. Running faster does not produce more data; it produces rate-limit errors.
- A rate-limit response is retried up to twice, waiting the retry interval the API returns. Retries do not contaminate the timing: only the successful attempt is recorded, and the waiting is excluded.
- Failed iterations are recorded as samples with their HTTP status and the server request id, excluded from the statistics, and counted in the output. A run with a high failure rate cannot be quoted as though it were clean.
- Percentiles are nearest-rank: sort ascending, take the value at index ceil(p ÷ 100 × n) − 1. Nearest-rank always returns a value that was actually observed, whereas an interpolated p95 is a number nothing ever did.
- A dated JSON file is written containing every individual sample, the summary statistics, the environment, the configuration and the run limitations. The raw file is what makes a published percentile checkable, so it is published alongside any figure taken from it.
Sample sizes and what they support
Under the nearest-rank definition a percentile needs ceil(1 ÷ (1 − p)) samples before it means anything. Below that threshold the reported figure is simply the largest observation. The harness computes all four percentiles regardless, but it prints NOT SUPPORTED beside any the sample size does not carry, and the type that models a published benchmark requires the same list — so an unsupported percentile cannot reach this page unless somebody types it in on purpose.
| Percentile | Minimum samples | Collection time at ~20/hour |
|---|---|---|
| p50 | 2 | ~6 minutes |
| p90 | 10 | ~30 minutes |
| p95 | 20 | ~1 hour |
| p99 | 100 | ~5 hours |
Reproduce it yourself
The harness is one dependency-free TypeScript file, tools/latency-benchmark/run.ts, with its documentation in tools/latency-benchmark/README.md. It needs Node 22.18 or newer and no install step, so it can be copied out and run against your own key. That is deliberate: a benchmark nobody outside the company can run is not a benchmark.
REXA_API_KEY='vk_...' \
REXA_BENCH_LOCATION='London, UK — residential fibre' \
REXA_BENCH_NETWORK='940 Mbit/s down, 9 ms RTT to 1.1.1.1, 0% loss' \
node --experimental-strip-types tools/latency-benchmark/run.tsThe location and network variables are required, not decorative. The run refuses to start without them, because a result that does not say where it was taken from cannot be compared with one that does. Add --dry-run to validate configuration without calling the API, or --help for the full option list.
The API key is read from an environment variable and is never printed or written to the output file. Neither are the room join token or room URL, which are credentials for a live room. Result files are therefore safe to publish as-is — which is the point, since the raw file is what makes a percentile checkable.
If you run it and get a result that contradicts anything we later publish, we want to know. Tell us, and send the JSON.
Customer results
We have not published a customer case study. There are no logos on this site, no testimonials, and no “customers see X%” figures, because none of those exist yet in a form we could show you the working for.
When one is published it will carry all of the following, because the content model behind this page will not compile without them:
- the customer named, with written permission on file to publish their name, the figures and the quote
- the situation before, measured on the same basis as the situation after
- every outcome accompanied by how it was measured — which system produced the number, over what window, excluding what
- call volume, with the system that reported it
- an attributed quote from a named person in a stated role
- the limitations: confounders, what else changed at the same time, and anything that moved the wrong way
- a named author, a named reviewer, and both dates
What a published benchmark will contain
So you can hold us to it, here is the full list. Every item is a required field on the type that models a benchmark in our codebase; a result missing any of them is a build failure rather than a judgement call.
- the hypothesis the run set out to test, stated so that it could have come out the other way
- the full methodology, specific enough to repeat without asking us
- sample size, test dates, geography, carriers and languages
- measured network conditions during the run
- the exact speech, model, voice and turn-detection configuration
- p50, p90, p95 and p99 — together with the list of which of those the sample size actually supports
- a public link to the raw per-sample JSON
- the limitations, including where the result may mislead
- reproduction instructions and the harness path
- a named author and a named reviewer who is not the author
- the date published and the date last reviewed
Last reviewed