Hysen Labs
Open-source project
Kludex/zuvloop avatar
Kludex

zuvloop

A libuv event loop for asyncio, written in Zig.

40 stars3 forksPythonMIT
DEEP OPEN-SOURCE ANALYSIS

Zuvloop is a drop-in asyncio event loop written in Zig

Zuvloop replaces the standard asyncio event loop with a libuv powered implementation written in Zig, keeping the same Python API while raising scheduling throughput.

What zuvloop replaces

Zuvloop is a replacement for the built-in asyncio event loop in CPython. The pitch is simple: your code stays the same, but the loop underneath runs faster. It is built on libuv, the same event engine that powers Node.js, and the native parts are written in Zig rather than C. The README states that scheduling, timers, sockets, and DNS all run in native code driven by libuv. On thread safe scheduling the project claims more than 25 times the throughput of stock asyncio, and it reports beating uvloop on 10 of 11 benchmarks shown in the table. The drop-in nature matters because most asyncio code never names the loop directly. You import zuvloop and call its run function, or hand its loop factory to asyncio.run, and the rest of your coroutines, tasks, protocols, and APIs are unchanged. The project ships type hints for everything and passes strict mypy, so editors get full completion and checking. It also builds in OpenTelemetry instrumentation that is free until you turn it on, emitting slow callback spans, unhandled exception spans, and loop metrics. The README targets Python 3.14 and mentions the new asyncio introspection tools such as python -m asyncio ps and call graphs. That modern baseline is part of the design, since the native layer is written against current CPython internals. For anyone running networked Python services, the appeal is higher request rates without rewriting application logic.

Benchmarks and requirements

The README includes a benchmark table measured with the suite in the benchmarks directory on an M3 Max running macOS 26, CPython 3.14.3, and libuv 1.51.0. Each result is the median of seven interleaved in-process runs or five interleaved HTTP runs. The numbers show zuvloop leading asyncio and uvloop on call_soon at 8.80 million per second, call_soon with arguments at 9.39 million per second, and call_soon_threadsafe at 12.4 million per second. Timer schedule and cancel reaches 9.21 million per second, bulk stream 9.2 gibibytes per second, and echo round trips at 1 kibibyte 59.7k per second. Under uvicorn plaintext it reports 69.5k requests per second and under aiohttp server 42.5k per second, tying uvloop on the aiohttp client at 12.2k per second. The getaddrinfo numeric host path hits 1.73 million per second. Requirements are Python 3.14 or newer on Linux, macOS, or Windows, with prebuilt wheels for common architectures. Source builds install a pinned Zig 0.16 toolchain in an isolated environment, and direct native development needs Zig 0.16 on the path. Free threaded CPython builds are not supported and fail explicitly at build time. The architecture notes credit argument storage inside handles, a native timer heap, per turn vectored write batching, zero copy reads, and a getaddrinfo fast path for address literals as the reasons for the speed.

Installing and using it

Installation is a single pip command, pip install zuvloop, which pulls a prebuilt wheel on supported platforms. The README shows two usage styles. The first replaces the top level runner: import zuvloop and call zuvloop.run(main) where main is your coroutine, as in the example that opens a connection to example.com on port 80, writes a minimal HTTP GET, drains, reads, and closes. The second style keeps asyncio.run and passes loop_factory=zuvloop.new_event_loop so existing entry points need only a small edit. Both paths keep Task objects, protocols, and the standard asyncio APIs intact, which is the whole point of the drop-in claim. Because the project is fully typed and strict mypy clean, type checkers see zuvloop's loop as a normal asyncio loop. The optional OpenTelemetry hooks let operators trace slow callbacks without paying for that cost in the hot path until they enable it. The documentation site linked from the README explains the design in more depth, including the native timer heap and write batching. Prebuilt wheels cover Linux x86-64 and AArch64, macOS x86-64 and arm64, and Windows AMD64 and ARM64, so most developers can install without a Zig toolchain. Anyone on an unsupported architecture falls back to the source build with its pinned Zig 0.16 environment.

Editorial conclusion

The project is published under the MIT license and is a Python package with a Zig core, available at the Kludex zuvloop repository.

DEEP OPEN-SOURCE ANALYSIS

Official sources

Community notes

Community notes