# zzz: a Zig HTTP server built on a pluggable async runtime

> A Zig framework for networked services that lets the consumer supply the async implementation, so the same HTTP and HTTPS server code runs on io_uring, epoll, kqueue or poll, with a router, middleware, memory pooling and TLS handled by a separate library.

**tardy-org/zzz** — A framework for writing performant and reliable networked services.

- Repository: https://github.com/tardy-org/zzz
- Stars: 794 · Forks: 39
- Language: Zig
- License: MPL-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/tardy-org-zzz

## The async implementation is the injection point

zzz is described as a framework for writing performant and reliable networked services in Zig, supporting both HTTP and HTTPS. The design decision that defines it is that it focuses on modularity and portability, allowing you to swap in your own implementations for various things. Consumers can provide an async implementation, which is what allows it to be used in standard servers as well as in embedded and bare metal domains.

The practical effect is that the async backend is not a build flag but a dependency you supply. The framework supports four:

- `io_uring` for Linux, at version 5.1.0 or later.
- `epoll` for Linux, at version 2.5.45 or later.
- `kqueue` for BSD and Mac.
- `poll` for Linux, Mac and Windows.

That list is the whole portability story. A service that wants the throughput of io_uring on a modern Linux server and the portability of poll on a platform without it is the same codebase, and the async layer is where the two diverge.

Underneath sits Tardy, described as an asynchronous runtime, and the project notes that the recent migration to Tardy is what made the performance claim possible. TLS is handled by a separate library, secsock, rather than being part of zzz itself, which is a clean separation that keeps the core free of cryptography.

The other structural pieces are a layered router including middleware, single and multithreaded support, and memory pooling for minimal allocations. The primary language is Zig and the licence is MPL-2.0.

## Installing means fetching a dependency into build.zig

There are two supported ways to get zzz, and the difference between them is which Zig version and which versions of its dependencies you are committing to.

For development, zzz uses the main branches of tardy and secsock, and Zig `0.17.0-dev.1454+5faa79730`. The command to fetch it is:

```elvish
zig fetch --save 'git+https://github.com/tardy-org/zzz?ref=main#commit_hash'
```

For a release, the latest is `v0.3.2`, which uses tardy `v0.3.2`, secsock `v0.1.2` and Zig `0.16.0`:

```elvish
zig fetch --save 'git+https://github.com/tardy-org/zzz#v0.3.2'
```

Either way, the fetched dependency is then wired into `build.zig`:

```zig
const zzz = b.dependency("zzz", .{
    .target = target,
    .optimize = optimize,
}).module("zzz");

exe.root_module.addImport(zzz);
```

The `zig fetch --save` pattern is the standard way Zig packages are consumed, and the save flag records the dependency in `build.zig.zon` so the build is reproducible. The `build.zig` snippet shows that zzz is consumed as a module and imported into the executable's root module, which is why the dependency takes the target and optimize mode as parameters.

The version matrix is worth noting. A development checkout wants a development build of Zig, while the release wants Zig `0.16.0`. If your project is on a stable Zig release, the `v0.3.2` path is the one that works, and the documentation points at two further pages: Getting Started and HTTPS, both in the `docs/` directory of the repository.

## The performance numbers come with a specific caveat

The optimisation section makes strong claims, and the way they are qualified is what makes them useful.

The project says zzz is very fast, and that a combination of methods such as allocation at start up and avoiding thread contention lets it extract a lot of performance out of a fairly simple implementation. It also says zzz is holding up well in practice but is still early stage software, and that it has been running in production serving the author's own site.

The comparison is with gnet, described as the fastest plaintext HTTP server according to TechEmpower. The claim is that after the migration to tardy, zzz is about as fast as gnet while consuming only about 22 percent of the memory gnet requires. The repository ships the benchmark images and the raw CSV data behind them, under `docs/benchmark/`.

The second benchmark is more specific. On a CCX63 instance at Hetzner with 2000 maximum connections, the project reports being 70.9 percent faster than zap and 83.8 percent faster than http.zig, while using only about 3 percent of the memory used by zap and about 1.6 percent of the memory used by http.zig.

The configuration angle matters as much as the numbers. zzz can be configured to use minimal memory while remaining performant, and the provided `minram` example uses only 256 kB. That figure is the one to hold on to if you are running zzz on a constrained device, and it is a different question from how fast it is on a dedicated server.

What the numbers do not cover is stated: no TLS benchmark, no HTTP/2, and no comparison against servers that are not event loop based. The plaintext comparison is against a peer group, and the memory comparison is the part with the largest margin.

## The example folders are the documentation of the feature surface

The `examples/` directory is the clearest inventory of what zzz actually does, and it is worth reading before the API documentation.

There is `examples/basic/`, which is the minimal starting point. `examples/middleware/` covers the layered router. `examples/form/` is a form handling example, which for an HTTP server means request body parsing. `examples/cookies/` shows session or cookie handling. `examples/sse/` is server sent events, which matters for a framework that has to hold long lived connections. `examples/tls/` is the HTTPS path, and `examples/fs/` serves files from the filesystem. `examples/unix/` is the one worth a second look, because it points at the Unix domain socket support, which is the embedded and bare metal use case the modular async design exists to serve.

Nine examples covering a router, middleware, form parsing, cookies, streaming responses, TLS, static files and Unix sockets is a substantial surface for a framework at version 0.3.2, and it is a reasonable proxy for how much of the common HTTP server functionality is already handled rather than left to the user.

The repository layout also has the supporting pieces a Zig project needs: `build.zig` and `build.zig.zon` at the root, a `flake.nix` with a `flake.lock` for reproducible development environments, a `docs/` directory, and `src/`.

The documentation directory is linked from the README for two specific topics, Getting Started and HTTPS. That suggests the deeper documentation is organised by task rather than by API, which is a reasonable choice for a framework whose main selling point is that you can choose your own async implementation.

## Alpha status is the first thing to plan around

The README carries an important notice in a callout box, and it should shape your evaluation rather than sit at the bottom of a page.

zzz is currently alpha software, and there is still a lot changing at a fairly quick pace, with certain places where things are less polished.

The version history is consistent with that. The releases are v0.3.2 from June 2026, v0.3.1 from April 2026, and v0.3.0-rc1 from January 2025, so a release candidate in early 2025 led to two patch releases spread across the following eighteen months. Combined with the development branch tracking a Zig development build rather than a stable one, the picture is of a project where the underlying toolchain is still moving underneath it.

The repository is not archived and the last push was on 2026-09-16, so the work is live rather than abandoned.

Two consequences follow. First, an API you build against today may change, and since the project is at 0.x, the changes come without the long deprecation cycles a stable library would offer. Second, the dependency pins are part of the contract: the release wants Zig `0.16.0`, and the development branch wants a specific `0.17.0-dev` build. If your own project is on a different Zig version, that is a hard constraint before any other consideration.

The contribution terms are also stated plainly, and they are worth knowing before you send a patch. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in zzz shall be licensed as MPL2.0, without any additional terms or conditions.

## Conclusion

Adopt zzz if you are writing a networked service in Zig and want a small HTTP and HTTPS stack with a swappable async backend and the option to run bare metal. Do not adopt it for production traffic on anything you cannot afford to rewrite, because the project states it is alpha software with a lot changing at a fairly quick pace. Verify first which Zig version your target needs, since the release and the development branch pin different ones, and read the getting started and HTTPS documents before you commit to its API.

## FAQ

### What is zzz?

It is a framework for writing performant and reliable networked services in Zig, supporting both HTTP and HTTPS, focused on modularity and portability so that you can swap in your own implementations and supply your own async implementation.

### How do I add zzz to a Zig project?

Fetch the dependency with `zig fetch --save 'git+https://github.com/tardy-org/zzz#v0.3.2'`, then add it in build.zig with `b.dependency("zzz", .{ .target = target, .optimize = optimize }).module("zzz")` and import it with `exe.root_module.addImport(zzz)`.

### Which async backends does zzz support?

io_uring for Linux 5.1.0 or later, epoll for Linux 2.5.45 or later, kqueue for BSD and Mac, and poll for Linux, Mac and Windows. The consumer supplies the async implementation.

### Is zzz ready for production use?

The project states it is currently alpha software with a lot changing at a fairly quick pace, and that it is still early stage software even though it has been running in production serving the author's own site.

### What licence is zzz released under?

MPL-2.0, and unless a contributor explicitly states otherwise, any contribution intentionally submitted for inclusion in zzz is licensed as MPL2.0 without additional terms or conditions.

## Sources

- [Issues](https://github.com/tardy-org/zzz/issues)
- [License: MPL-2.0](https://github.com/tardy-org/zzz/blob/main/LICENSE)
- [README](https://github.com/tardy-org/zzz/blob/main/README.md)
- [Releases](https://github.com/tardy-org/zzz/releases)
- [tardy-org/zzz on GitHub](https://github.com/tardy-org/zzz)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tardy-org-zzz
