Skip to main content

aiopquic - Async QUIC + WebTransport (picoquic)

aiopquic is a Python/Cython binding to picoquic, providing high-performance QUIC transport and WebTransport for asyncio applications.

Overview

aiopquic exposes picoquic's QUIC implementation through a lock-free SPSC ring buffer architecture that bridges the picoquic network thread with Python's asyncio event loop. It provides an asyncio QUIC/HTTP3 transport API in the spirit of aioquic (and its fork qh3) — similar shapes for QuicConfiguration, QuicConnection, connect / serve, and event types — plus a native WebTransport client/server layered on picoquic's H3 + h3zero. Not a drop-in replacement: semantics differ around backpressure (send_stream_data raises BufferError on full per-stream ring) and flow-control sizing.

Architecture

  • SPSC Ring Buffers -- Lock-free single producer/single consumer rings for event passing between threads, separate TX and RX rings per TransportContext.
  • TX path -- Asyncio pushes into per-stream byte ring; picoquic pulls at wire rate via prepare_to_send.
  • RX path -- picoquic pushes per-event StreamChunks; ownership transfers at pop for 1-copy delivery.
  • Cross-platform wake fd -- Linux eventfd for efficient asyncio add_reader() notification; pipe() self-pipe fallback on macOS / BSD.
  • Dedicated Network Thread -- picoquic runs in its own thread via picoquic_start_network_thread(). One worker thread per TransportContext; multiple contexts share the asyncio event loop within a single Python process.
  • Cython Bridge -- Thin Cython layer over C callbacks, minimal overhead.
  • WebTransport -- asyncio.webtransport.WebTransportSession (client + server) over picoquic's picowt_* API and h3zero.

Features

  • QUIC client and server: connect, serve, QuicConnectionProtocol
  • Stream data send/receive with FIN signaling, stream reset, stop_sending
  • WebTransport client + server: serve_webtransport, WebTransportSession
  • QUIC datagram TX + RX (note: WebTransport datagram TX not yet wired)
  • Connection migration / 0-RTT (inherited from picoquic)
  • Connection management: create, close, idle timeout, application close codes
  • Per-cnx multiplexing on the server side via QuicEngine
  • TLS keylog (NSS Key Log Format) for pcap decryption
  • Native picoquic_ct / picohttp_ct subprocess smoke (catches upstream regressions on every submodule update)

Performance

Multi-Gbps sustained throughput over loopback on commodity hardware: 2+ Gbps through the full asyncio API at the QUIC default MTU (where the kernel's sendmsg syscall rate is the wall), 11+ Gbps protocol-only. Numbers, methodology, reproduction commands, build flags, and runtime tuning (jemalloc, GSO, wake thresholds) live in PERFORMANCE.md. The TX/RX dataflow and flow-control model — including the TX backpressure configuration parameters — are documented in DATAFLOW.md.

Installation

Wheels for cp312 / cp313 / cp314 on Linux (manylinux_2_34, glibc 2.34+) and macOS arm64 are published to PyPI:

uv pip install aiopquic     # or: pip install aiopquic

For older Linux (glibc 2.28–2.33) install via sdist; build toolchain required.

From source

git clone https://github.com/gmarzot/aiopquic.git
cd aiopquic
git submodule update --init --recursive
./bootstrap_python.sh    # creates .venv with uv-managed Python 3.14 (GIL build) and pins cython 3.2+
source .venv/bin/activate
./build_picoquic.sh      # builds picotls, picoquic, native test drivers
uv pip install -e '.[dev]'    # or: pip install -e '.[dev]'

On macOS, set OPENSSL_ROOT_DIR if Homebrew OpenSSL is not auto-detected (the build script tries openssl@3 then openssl@1.1).

Reporting issues

Include the full version report in any issue — it captures aiopquic plus the picoquic + picotls submodule SHAs the binding was built from:

python -m aiopquic.versions   # or the console script: aiopquic-versions

Sample output:

aiopquic:  0.3.7.dev12+g6eef9caf6 (~/Projects/moq/aiopquic/src/aiopquic) [2026-06-12 08:55]
  - picoquic:  1.1.49.2 (d6c5653d) [2026-06-05]
  - picotls:   master (bfa67875) [2026-04-20]

If you're running aiomoqt on top, prefer python -m aiomoqt.versions — it chains through to this report and includes the aiomoqt version too.

Usage

Low-level Transport API

from aiopquic._binding._transport import TransportContext

server = TransportContext()
server.start(port=4433, cert_file="cert.pem", key_file="key.pem", alpn="moq-00", is_client=False)

client = TransportContext()
client.start(port=0, alpn="moq-00", is_client=True)
client.create_client_connection("127.0.0.1", 4433, sni="localhost", alpn="moq-00")

Asyncio API

from aiopquic.asyncio.client import connect
from aiopquic.quic.configuration import QuicConfiguration

configuration = QuicConfiguration(alpn_protocols=["myproto"], is_client=True)

async with connect("server", 4433, configuration=configuration) as protocol:
    quic = protocol._quic
    stream_id = quic.get_next_available_stream_id()
    quic.send_stream_data(stream_id, payload, end_stream=True)
    protocol.transmit()

payload is opaque bytes; the library doesn't impose framing. Consumers that want HTTP/3 layer on top of aiopquic's picowt-backed h3zero plumbing; consumers that want WebTransport use serve_webtransport / connect_webtransport. Most direct users of the asyncio API ship their own protocol bytes (MoQT, custom binary frames, etc.).

WebTransport

from aiopquic.asyncio.webtransport import (
    serve_webtransport, WebTransportSession,
)
# See src/aiopquic/asyncio/webtransport.py and tests/ for full examples.

Development

uv pip install -e '.[dev]'    # or: pip install -e '.[dev]'
python -m pytest tests/ -v -m "not interop and not native"

# Microbenches (opt-in)
python -m pytest tests/bench

Test-suite coverage, benchmark methodology, performance builds (AIOPQUIC_PERF=1, io_uring scaffolding), and runtime tuning are documented in PERFORMANCE.md.

Known Limitations

  • Free-threaded Python (3.14t) not yet supported -- the TX-ring producer side, TransportContext lifecycle, and the WebTransport engine state currently rely on the GIL for serialization. FT support deferred until a per-context locking audit lands.
  • STOP_SENDING error codes surface as 0 today: picoquic's public stream-error getter only returns the RESET_STREAM code. STOP_SENDING's code lives in stream->remote_stop_error in picoquic_internal.h (no public getter). A small helper that pulls the field is straightforward future work — see TODO in src/aiopquic/_binding/c/callback.h.

TODO

  • Windows support (eventfd alternative — IOCP / WSAEventSelect on the wake-fd path)
  • Free-threaded Python (3.14t) support after producer-side locking audit
  • STOP_SENDING error-code surfacing helper (read remote_stop_error from picoquic_internal.h)
  • WebTransport datagram TX path through the C bridge
  • Datagram benches: latency percentiles, payload-size sweep, loss / jitter under load (today's bench_datagram is fire-and-count throughput only)
  • Pure stream open/close microbench (lifecycle rate without payload, separate from bench_stream_churn_highlevel which bundles writes + FIN)
  • Submit aiopquic to the QUIC interop runner for cross-implementation coverage

Resources



A Marz Research project.
Author: G. S. Marzot <gmarzot@marzresearch.net>

License

MIT License -- see LICENSE

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aiopquic-0.3.10.tar.gz (3.3 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

aiopquic-0.3.10-cp314-cp314-manylinux_2_34_x86_64.whl (5.3 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.34+ x86-64

aiopquic-0.3.10-cp314-cp314-manylinux_2_34_aarch64.whl (5.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.34+ ARM64

aiopquic-0.3.10-cp314-cp314-macosx_14_0_arm64.whl (3.9 MB view details)

Uploaded CPython 3.14macOS 14.0+ ARM64

aiopquic-0.3.10-cp313-cp313-manylinux_2_34_x86_64.whl (5.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

aiopquic-0.3.10-cp313-cp313-manylinux_2_34_aarch64.whl (5.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ ARM64

aiopquic-0.3.10-cp313-cp313-macosx_14_0_arm64.whl (3.9 MB view details)

Uploaded CPython 3.13macOS 14.0+ ARM64

aiopquic-0.3.10-cp312-cp312-manylinux_2_34_x86_64.whl (5.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

aiopquic-0.3.10-cp312-cp312-manylinux_2_34_aarch64.whl (5.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ ARM64

aiopquic-0.3.10-cp312-cp312-macosx_14_0_arm64.whl (3.9 MB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

File details

Details for the file aiopquic-0.3.10.tar.gz.

File metadata

  • Download URL: aiopquic-0.3.10.tar.gz
  • Upload date:
  • Size: 3.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for aiopquic-0.3.10.tar.gz
Algorithm Hash digest
SHA256 c9ec6fbc67e2dc1d8b2dfec63ccf7b98945d6bf4b2f20f6e57c136b551dd1929
MD5 2ca63f78d582e31edabf2dcad43d9941
BLAKE2b-256 b9e980a070d82c49c7020cef20dac80e24472b3f9f5b0be30c25a7d80adde72b

See more details on using hashes here.

File details

Details for the file aiopquic-0.3.10-cp314-cp314-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for aiopquic-0.3.10-cp314-cp314-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 9e9696c34e895ea15a08d49a6f12fa373dd3373fdca3a80a38e1ca6c9e4d6f44
MD5 032fdd01065ad721f85b3651ab91823d
BLAKE2b-256 4ad07817f240eb714725c472df98e43c528f58d470932931c5e008365c7bfb7a

See more details on using hashes here.

File details

Details for the file aiopquic-0.3.10-cp314-cp314-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for aiopquic-0.3.10-cp314-cp314-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 965a18579293c93502b1a0f04a337b57c2bf26aad0b614b0065be28bbff3a318
MD5 236df55f4f45728e1495f66b2d7f50f6
BLAKE2b-256 1c871f9a731ccc625cfd5636fcb68bdb11de6750669ae54460cbcf2b6e43c9d4

See more details on using hashes here.

File details

Details for the file aiopquic-0.3.10-cp314-cp314-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for aiopquic-0.3.10-cp314-cp314-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 ff1afbf432a08ddb914c2d36017e0858fa1fd60e815fe2876d8972dbb5cf05ef
MD5 dabf07e59ffa4b32eebd146e4835d95d
BLAKE2b-256 2c7b59fe37df55ccfcbadcf5c5dd90f56cd373e2000fbb0ca607f38788fe8ac3

See more details on using hashes here.

File details

Details for the file aiopquic-0.3.10-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for aiopquic-0.3.10-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 f3e040c26cb71964d1365fe599df957c0649aad2d74dd81a6860c89cefa1b39b
MD5 45c5a8b3c98aabd0a8fd31debcf4770f
BLAKE2b-256 e41d4e584bc5410a522049e242f02b3a68b132949e115f7b95623ffb171c5169

See more details on using hashes here.

File details

Details for the file aiopquic-0.3.10-cp313-cp313-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for aiopquic-0.3.10-cp313-cp313-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 07baaa7fe75207f55d8ee61dae087f664f8d751d4efa33ffeeef19ebf692b34b
MD5 286f4c757d08bf2d9fdc338542a37b44
BLAKE2b-256 f17cbf2941093347162769d4be9440140ecb17f396a074cb148a25558045a55c

See more details on using hashes here.

File details

Details for the file aiopquic-0.3.10-cp313-cp313-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for aiopquic-0.3.10-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 c5c53c14c57e5c1d991c61579689427b7c6877d4c63588a338b02a773616a28e
MD5 f36fe0c6348908b93b5f473396c460eb
BLAKE2b-256 1d165b797fc7e0b936ddadf24ccf9b00bfe58a631dd35f5a95cb6c931a01671c

See more details on using hashes here.

File details

Details for the file aiopquic-0.3.10-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for aiopquic-0.3.10-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 bd3273cd78151111a0b62f15d65e51215fbf327c8ac1ad0bab46e5b6c5b62d10
MD5 983f9578101c33f0966904ef36f66087
BLAKE2b-256 c77e3c6a4158d1d01340c0a9ae3394966552fc4b76ce889e07731b5d05bae031

See more details on using hashes here.

File details

Details for the file aiopquic-0.3.10-cp312-cp312-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for aiopquic-0.3.10-cp312-cp312-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 aa11d3b1343e1169d6ea15e49dfeec5c1db5c0011a0abf22841d4c9b6a37b003
MD5 ec97191d14532272a2e5a6305c038a8f
BLAKE2b-256 f9d196e8855ba2cd70f78aeea3b3f13da01ddb707644d0ea9dc47ad3f70c8d82

See more details on using hashes here.

File details

Details for the file aiopquic-0.3.10-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for aiopquic-0.3.10-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 ba3807d8df3b11679008273fdd484afe984286a5748f2335fc9a7dc2045f50c3
MD5 50894ab5d3737268bda10d960208ce80
BLAKE2b-256 0ebe1a5a0c2ca5aff8e034e100ed0fdd1a22cb6e2eb4cfdc329a1e871295a451

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.11

10 files

This release

0.3.10 This release

10 files

0.3.9

10 files

0.3.8

10 files

0.3.7

10 files

0.3.6

10 files

0.3.5

10 files

0.3.4

10 files

0.3.3

7 files

0.3.2

7 files

0.3.1

7 files

0.3.0

7 files

0.2.7

7 files

0.2.6

7 files

0.2.5

7 files

0.2.4

7 files

0.2.3

7 files

0.2.2

7 files

0.2.1

7 files

0.2.0

7 files

0.1.0

1 file

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page