Skip to main content

High-performance QUIC/HTTP3 library — picoquic-backed, qh3-compatible asyncio API

Project description

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

Project details


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.9.tar.gz (770.3 kB 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.9-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.9-cp314-cp314-manylinux_2_34_aarch64.whl (5.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.34+ ARM64

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

Uploaded CPython 3.14macOS 14.0+ ARM64

aiopquic-0.3.9-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.9-cp313-cp313-manylinux_2_34_aarch64.whl (5.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ ARM64

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

Uploaded CPython 3.13macOS 14.0+ ARM64

aiopquic-0.3.9-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.9-cp312-cp312-manylinux_2_34_aarch64.whl (5.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ ARM64

aiopquic-0.3.9-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.9.tar.gz.

File metadata

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

File hashes

Hashes for aiopquic-0.3.9.tar.gz
Algorithm Hash digest
SHA256 c09d379bcfd59a15ed824698bb6400f7e6d9d13a00a6ae705924fa9a8f6aa5dc
MD5 7ef95520b1baf695462b18a092d161c8
BLAKE2b-256 1c5f78716f6ccfaaa858773e3c35d0c63fbd892696e2ecea398a959ed715c60f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aiopquic-0.3.9-cp314-cp314-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 f508a782bb9833e684432ae0c9474b818d6ffda3e7283204fe2f9dccddcbc021
MD5 039313abf52c6e8b02c2d2b909cdd2e5
BLAKE2b-256 90fedb86f83cd35e9b1b6b543a3ce22d54060981c95419fd771fc1f18e7f4e40

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aiopquic-0.3.9-cp314-cp314-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 cfbb35e360d38df1552a60e1d3a1875d17967ffbb7794c5c359adb76b5b299b9
MD5 446f62e2eb6c6e8a429748afc42c564e
BLAKE2b-256 c706ba5dbfc32f45182cf0eca7206f794b2a0c04aa702bf55b0bb731b5edd4c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aiopquic-0.3.9-cp314-cp314-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 7d560db03ab37bbc2956143188bcf3e7b34d0ab4cbb4938f97890b930a0786f6
MD5 085380aac33b5df7fb52c3b2d423b6e0
BLAKE2b-256 400005ca2db5fac1b5708d7a58b7c107355fd124aad548f637de5ef78477dc7a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aiopquic-0.3.9-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 d5219b6a0cfefc5e42faf37b9f8b2fb8348b80bec9827688d9183eb330347fa3
MD5 223b8c2fc635a4dc3ab1295f6372ff7b
BLAKE2b-256 192b8166e167c11606f751ab7afdfc5711dbcf56b99f4016c8d436a6c976c529

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aiopquic-0.3.9-cp313-cp313-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 662a8b38f6577f7dc3cc82717f4e3fd2b975ffb5f328ef120cca5d6b18fbdb73
MD5 c709543b272504ad5709f72b6fdc9768
BLAKE2b-256 389b60474ad2b076985f769cc2497d00f49f8e264ac1489a17f3cabf5f6b0793

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aiopquic-0.3.9-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 5c405550c9bce6a7d6ac43c5f4d6e1d337b17e4b0e3faa6c30d96b19cdf28968
MD5 c537e94a15b85a5c179425b79d5f4468
BLAKE2b-256 6155d83fc33626857c81162ae5fb74faf49f8324a1beac70ef8ccbdd5139e18d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aiopquic-0.3.9-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 119791cd5a52f48b94f4f4b2f2bfa872d265e67b4c8c9911bb8ab27e54f7918b
MD5 037d744d0f49d325926bf77eb995b218
BLAKE2b-256 db98649ecb9bb2dd77cf92e935b0b1ae44d9433ac187c4971d52104edaaf5812

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aiopquic-0.3.9-cp312-cp312-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 1ca07f2c278a8a1cf44f2f3257369245e4e11fcedbd955d6cbe949cef5a5f577
MD5 1abf65b906ce43f00a61896f03fe6c42
BLAKE2b-256 50a8b114fc673ae70e3801cb2918fc5d1db05b599fd515baf8f386f80ac11575

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aiopquic-0.3.9-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 1a7dde9fccc30cf66e4a04e0dbb5c1d02bc87fff3d24fa35f788a42419f005df
MD5 25cf8fa1a0fc19755cf74700c8c5c502
BLAKE2b-256 d91d0363a4106aab6f9f54c6d733974975ac9b54eaa1e9868130fb9605a19a11

See more details on using hashes here.

Supported by

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