Skip to main content

rtpbench

Wire-level latency and conformance tests for voice agents over SIP/RTP.

rtpbench calls a voice agent over SIP, captures the RTP on both ends, and measures turn latency, barge-in and SIP behaviour from the packets themselves, on clean and impaired networks (tc netem). Every measurement carries an error bar calibrated against a reference agent that logs the truth, and every case is proven against that agent, passing and failing: rtpbench cases runs that proof on your host.

Status: early; commands and result formats can still change between releases.

What it found

Three open-source ways to put the OpenAI Realtime API on a SIP call, through 24 cases, with and without a carrier in front, on a mock engine that holds the AI engine's share of each turn fixed:

LiveKit AI Voice Connector CE at b95f5af Asterisk + AVA
cases failed of 24 5, and 2 unsupported 5, 3 unsupported and 1 inconclusive 4, and 3 inconclusive
turn latency, clean, p50 1833 ms 1511 ms 1589 ms
its own media path per turn, p50 335 ms 9 ms 88 ms
stops for an interruption, clean, p50 306 ms 24 ms never

The counts take every profile, direct and through the carrier, and AVA as it ships, over AudioSocket. Run direct only, as target NAME --mock does by default, LiveKit fails 4: late-offer fails only through the carrier. All three pass the 3 cases for lost SIP messages, run direct on a clean network. Unsupported is an optional feature declined as its RFC allows, with the call unharmed: LiveKit refuses DTMF by SIP INFO (405), AI Voice Connector CE refuses it (501) and negotiates no RFC 4733 events, and neither takes session timers. LiveKit does negotiate RFC 4733 events, but the digit never reaches the engine: a failure.

  • LiveKit keeps sending audio to a held caller in every kind of hold, AI Voice Connector CE when held with c=0.0.0.0, and both answer a re-INVITE that changes codec with the old codec. AVA sends RTP only while it speaks, so whether its media resumes after a hold cannot be judged, except over Asterisk's WebSocket channel, where Asterisk keeps sending to a held caller.
  • LiveKit's extra latency is its own media path: 326 ms per turn more than AI Voice Connector CE's, against 322 ms between their turn latencies.
  • LiveKit's RTP falls 20 ms behind its own timestamps 4 s into every call, so a receiver needs a 21 ms jitter buffer for it on a clean network; AI Voice Connector CE's needs 1.1 ms.
  • AI Voice Connector CE delivers the engine's speech sample for sample. LiveKit re-encodes it on the way, through its WebRTC room, and on a clean network stretches or cuts a pause by 20-40 ms in 6% of answers (10% in a second wave).
  • AVA, as its golden configuration ships, cuts the last 0.6 s of speech from every answer, over each of its three transports, and over Asterisk's WebSocket channel its pacer also breaks every answer with 7-10 short silences. It never stops for an interruption: it keeps the caller's audio from the engine while it speaks. Over AudioSocket under packet loss, the engine sometimes got silence instead of the caller (a squelch AVA has fixed since), so 5 more cases flip now and then.
  • AI Voice Connector CE's main branch fixed 4 of the 10 cases it failed in the baseline (a failed transfer no longer hangs up on the caller; compact headers, a bare a=ssrc and SIP over TCP are taken), and now declines a DTMF INFO with 501 where it left it unanswered. It still refuses an INVITE without SDP and answers no re-INVITE without one.

The details, commands, conditions and raw runs are in the baseline, AI Voice Connector CE at b95f5af, Asterisk + AVA and lost SIP messages, and every call's timeline on the results site.

Common ways of measuring turn latency have errors of their own: measured inside the agent, a turn misses the network (80 ms on an LTE path); an energy rule on a recording reads turns long, by 87-110 ms at the median. Each method against the truth: metrology.

Quick start

Needs Linux, Docker 28 or later with Compose, and uv. WSL2 runs it, but its clock can drift and step by far more than the error bars: read what calibrate warns about first (clock steps and rate).

uvx rtpbench calibrate --profiles clean --turns 5     # how exactly this host times the wire
uvx 'rtpbench[vad]' cases                             # prove every case against the reference agent
uvx 'rtpbench[vad]' target livekit --mock             # a bundled target, no AI account needed
uvx 'rtpbench[vad]' target sip:agent@host             # an agent of your own, the same way

The first three take about 1, 17 and 11 minutes, after pulling about 0.4 GB of Docker images (compressed) on first use; every target and the carrier take 1.5 GB (images). The last needs an agent that answers SIP; your own agent says what it needs, such as --network for one in Docker on this host.

Each run writes results/<timestamp>/ with the captures, summary.md and, for cases, report.html: a timeline of every call's SIP, speech and RTP. rtpbench index links every run under results/ from results/index.html; rtpbench COMMAND --help lists a command's options, defaults and valid names.

Documentation

Development

From a clone, uv run rtpbench (uv run --extra vad rtpbench for [vad]) runs the checkout's code, as the docs show it:

uv sync
uv run ruff format && uv run ruff check --fix
uv run mypy
uv run pytest

Licence

Apache-2.0, except targets/aivc/opensips.cfg, derived from AI Voice Connector CE's example and under its GPL-3.0-or-later, and targets/ava/ai-agent.yaml, derived from AVA's golden OpenAI configuration and under its MIT licence.

Metadata

Release files for rtpbench 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rtpbench 0.4.0
File Size Uploaded Provenance Actions
rtpbench-0.4.0.tar.gz 3.8 MB Without provenance Details for rtpbench-0.4.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for rtpbench 0.4.0
File Interpreter ABI Platform Actions
rtpbench-0.4.0-py3-none-any.whl Python 3 none any Details for rtpbench-0.4.0-py3-none-any.whl

Total release size: 7.7 MB

Release files / rtpbench-0.4.0.tar.gz

Download URL rtpbench-0.4.0.tar.gz
Size 3.8 MB
Tags Source
SHA-256 checksum
How to use checksums
8df7912ff954a55570eba9281e38678aabaf7445acb3aaf93ea64e075f8d9b41
BLAKE2b-256 checksum
How to use checksums
9a1a96716e300526378f57564a4ca5e9ce6a6a4ed5e03dbfb2a4f0dee134a6da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / rtpbench-0.4.0-py3-none-any.whl

Download URL rtpbench-0.4.0-py3-none-any.whl
Size 3.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
fac80659f424c63b7c4e04113992d08778cd5d81a624c3ea6d5989b1f723ca87
BLAKE2b-256 checksum
How to use checksums
fb64b98fef282fca05567beacc4cff3cd8cd4da3f738680ccc5a574fcd71fe25
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for rtpbench 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page