A drop-in asyncio event loop for CPython, backed by zio.ev — the completion-based event loop from zio (io_uring on Linux, kqueue and IOCP elsewhere). Like uvloop, but on zio.ev instead of libuv, and with real asynchronous file I/O.
import asyncio
import blazio
async def main():
reader, writer = await asyncio.open_connection("example.com", 80)
writer.write(b"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n")
await writer.drain()
print(await reader.read())
writer.close()
asyncio.run(main(), loop_factory=blazio.new_event_loop)That loop_factory argument is the only change; the rest of your program is
standard asyncio.
blazio.open() is an aiofiles-compatible API over zio.ev's file completions —
real asynchronous file I/O, not a thread pool.
async with blazio.open("access.log") as f:
async for line in f:
...Seekable files also support positional pread/pwrite.
About 1.15x uvloop on transport-based HTTP. Measured on one Linux machine
(io_uring, CPython 3.12, ReleaseFast): 20 s wrk runs after a 30 s settle,
100 connections. benchmarks/ reproduces them.
Both drive the Transport/Protocol layer, which is what real servers (uvicorn,
aiohttp, asyncio streams) run on. The low-level loop.sock_* API is a separate
path that the three loops optimize very differently, so it is not benchmarked
here.
benchmarks/mini_http_server.py — a minimal Protocol writing a fixed 1 KB
response, with no framework in the path, so this is close to raw loop overhead:
| loop | req/s | p50 | p90 |
|---|---|---|---|
| asyncio | 101,428 | 0.91ms | 1.03ms |
| uvloop | 127,036 | 0.74ms | 0.81ms |
| blazio | 144,781 | 0.64ms | 0.88ms |
benchmarks/uvicorn_server.py — the same response through uvicorn. Most of each
request is now framework Python that every loop pays equally, so all three drop
sharply while the ratio between them holds:
| loop | req/s | p50 | p90 |
|---|---|---|---|
| asyncio | 23,501 | 4.02ms | 4.27ms |
| uvloop | 41,596 | 2.29ms | 2.35ms |
| blazio | 48,274 | 1.74ms | 2.53ms |
pip install blazioPrebuilt wheels cover Linux (x86_64), macOS (arm64), and Windows (x86_64) on CPython 3.12, 3.13, and 3.14. On other platforms pip builds from source; the build pulls in Zig on its own, so no toolchain setup is needed either way.
From a checkout, with the tests:
pip install .
python -m pytest tests/MIT. See LICENSE.