Skip to content

lalinsky/blazio

Repository files navigation

blazio

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.

Async files

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.

Performance

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

Install

pip install blazio

Prebuilt 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/

License

MIT. See LICENSE.

About

Alternative asyncio event loop

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages