I really like Zig. I have never wanted to write manually memory-managed code before. I don’t like C because it seems opaque and dangerous and I don’t like Rust for purely aesthetic reasons; but Zig is shiny and new and pretty and I can understand it intuitivly.
I wanted to write a small HTTP service in Zig (0.15.2) that used SQLite as a data store and could scale up. To do this I used the [http.zig](https://github.com/karlseguin/http.zig) and [zig.sqlite](https://github.com/vrischmann/zig-sqlite) libraries which are pretty stable. I spent a couple weeks on this project, but kind of hit a few walls all at once which has lead me to the decision to abadon the spike.
I am just going to record for my own sake the problems that I had, so when come back I can pick Zig up where I left off.
Things that are awesome
- It is so fast, soooo fast. In testing it is easily 2x faster than the exact same Go service deployed on fly.io.
- Allocators are very understandable. Also finding memory leaks is pretty easy since you can report unallocated memory at the end of a program. Using arena allocators during a HTTP call also removes a lot of stress.
- The concurrency with threads is not too complicated with mutexes, Signals and Events being pretty straight forward.
- comptime is super powerful because it is easy to use. Generating code that can pick up errors like
std.debug.print("{s}", .{} )removes runtime decisions and points of failure. I used comptime to generate an HTTP handler for static files, generate a struct that for DB migrations, and generate prepared SQL statements. - Zig’s learning curve is not too steep, there were a few days I got stuck on a problem, but was usually able to get through it with a increased understanding (instead of increased dislike) of Zig.
Problems:
- Not having a string type was less of an issue but
[]const u8,[]u8,[_]u8,[:0]const u8all being different really tripped me up a few times. - Lack of packages was fine for most things. I needed a SQLite pool, so I build it; needed a
.envparser, build it, needed a rate limiter, build it… A few things though were a bit more complicated, like an AWS S3 client. There are a few packages of unknown quality, and AWS does have a C S3 client. Finding something reliable without a giant amount of work might be impossible. - When
http.zigreceived a large volume of traffic callingserver.stopcauses a segfault. I think because it unallocates a requests currently being processed by a handler. This might be my fault, if I am holding it wrong but reliably shutting down was important for what I was building. zig build runswallows SIGTERMS so I have to usezig build && ./zig-out/bin/cmd. If you don’t thezig buildprocess will keep running when the application closes and you have to manually kill.- With the current 0.16.0 rewrite in IO layer, I think they removed some functionality like gzip. This made it difficult to implement compression for static HTTP handlers to save on bandwidth costs.
- Simple mistakes caused a lot of slowness, especially in the DB pool layer. Some thread mutex was too broad so one endpoint because very slow. Zig without my code is fast, but I can lose all benefit with small mistakes.
- Finding where memory is used is difficult. The process uses about 2x the amount of memory I think it should, it is not a memory leak but maybe I am allocating too many things just to be safe. Its not that bad, but I would like to be able to inspect the allocator during runtime and find where my memory is actually being used.
- AI/LLM/ Smart Autocomplete is a great tool to learn a programming language. This is limited with Zig and its fast moving standard library and API.
docker buildbreaks for zig on my mac and I can’t fix it. When finding the problem a common response is “you don’t need docker with zig”, but if you are deploying to fly.io (or a lot of other places) you do need docker. BTW it deploys fine, so I know the docker file is good.A lot of these problems may be my lack of understanding, or doing something wrong. I am sure a better programmer or someone who is more familiar with Zig could solve some of these issues. But I am just going to wait a bit before writing an HTTP service in Zig.
That being said, I still love Zig and want to use it for a project, I just don’t know what yet.