a lightweight http server for linux using io_uring
Find a file
Maakis Thoppae 45b38f67ca
fix build on zig master
seems like they've removed posix.close from std
2026-03-08 12:19:04 +00:00
assets add logo 2025-06-18 16:48:06 +01:00
src fix build on zig master 2026-03-08 12:19:04 +00:00
.gitignore delete all c files and update gitignore 2026-01-07 02:02:15 +00:00
build.zig fix cross compile on build 2026-01-10 23:25:20 +00:00
build.zig.zon initial zig project structure, and argument parser 2026-01-01 22:49:11 +00:00
LICENSE initial commit 2025-06-15 16:54:25 +01:00
README.md update readme's performance metrics 2026-02-09 17:27:39 +00:00

the takottpd mascot

takottpd

A lightweight, extensible HTTP server written in Zig, for Linux. Uses io_uring and tries to minimise memory allocations, data copies and memory usage. It requires kernel version 5.10 or above.

background:

Originally, I created a website with Go since i didn't want touch JavaScript, and it worked alright. The issue was that it wasn't fast enough on my Milk-V Duo S in which I host it on. I could have used nginx or something, but what's the fun in that? Might as well learn something new :)

status:

Rewritten in Zig, mostly because C was getting a bit annoying with not having things in its standard library. I ended up choosing Zig as its replacement since it has a pretty comprehensive stdlib with io_uring in it, and it's plently fast since it uses LLVM on the backend anyway.

performance:

Performance is actually slightly higher with Zig, and since Zig makes it easy to handle errors, it's also a lot safer. The hey tool (while serving this README.md file) reports 93965 reqs/sec with the zig version, whereas it reports 92551 reqs/sec with the C version. It's a mere ~1% increase, but still not bad.

Memory usage is higher, though still at a reasonable level.

Executable size (when using ReleaseFast and stripped) is actually far less than the C version (at least on x86-64)!

current features:

  • HTTP HEAD
  • HTTP GET
  • Directory selection
  • Custom error messages
  • Custom index pages
  • UTF-8 path support
  • Path sanitising
  • Basic caching
  • Date of file served in headers (zig doesn't seem to have this in std)
  • MIME types in headers
  • Pool allocator

known issues:

None so far :). There is io_uring fixed recv buffers I tried to get working, but had to revert since it was actually causing major reliability issues...

running:

Warning

I would highly recommend not just opening this to the internet since it's likely full of bugs and security holes. Tunnels would be a better option.

To build, you need to have the Zig compiler, specifically v16 or above.

Then build the project with this command:

zig build -Doptimize=ReleaseSafe

The binary will be in zig-out/bin/takottpd. From there you can just run it.

planned features and project goals:

  • Unicode file paths
  • Dynamically generate MIME types at startup using /etc/mime.types or otherwise (mime.zig already has a HUGE collection of mime types)
  • .so libraries that contain functions run on some requests
  • Handle GET request parameters
  • Respect HTTP caching standards
  • Cache using the LRU or Multi-Queue Algorithm
  • Warn and do something about the ulimit values
  • Create some sort of opcode parser instead of pointer to struct in io_uring event user data
  • Move statx() into io_uring
  • Cache file descriptors of all possible files before starting the server
  • Register file descriptors with io_uring
  • Don't cache files over a certain (user specified) size

sticker

If you end up hosting your site with this, make sure you put this sticker up! You can show off that you run the best HTTP server :P

a sticker saying powered by takottpd, with an image of the mascot on the left

Mascot drawn by an.chr.

Licensed with AGPLv3, happy hacking!

resources