Skip to content
M. Alkhatib
Projects
Public projectQuick Arm Webserver

qaws.

A small Zig static file server for finished assets behind a reverse proxy.

Why I made it.

I wanted a static file server that did the small origin-server job without becoming the whole edge stack.

A lot of deployments already have the public edge handled: TLS, routing, abuse protection, and proxying. Behind that, the application often only needs to expose a directory of finished files. qaws is for that narrow place.

The idea was to keep the server understandable, dependency-free, and efficient enough to feel comfortable on small Linux machines, ARM devices, and regular servers. It binds a port, serves the files, and keeps the rest of the infrastructure explicit.

Narrow on purpose

qaws serves finished static files. It does not try to become the TLS layer, authentication layer, upload handler, or dynamic application server.

Built for the proxy pattern

The intended shape is simple: a reverse proxy or tunnel handles the public edge, while qaws stays small behind it and serves the directory.

ARM was part of the point

The project was shaped with efficient ARM-based machines in mind, where low overhead and predictable concurrency matter.

What it does.

qaws is intentionally smaller than general-purpose webservers and reverse proxies. That is the point.

BUILT IN

  • Static GET and HEAD responses
  • HTTP keep-alive and ordered pipelining
  • Small-file cache fast path
  • Platform sendfile for larger file bodies
  • Strict JSON config with CLI overrides
  • Unix daemon and PID-file control

LEFT OUT

  • TLS termination
  • Authentication
  • Reverse proxying
  • Uploads or dynamic applications
  • Directory listings
  • Runtime compression

Measured, not promised.

Benchmarks depend on hardware, file shape, logging, and the exact client setup. I treat them as engineering feedback, not universal claims.

Recent cached small-file tests showed very high local throughput with access logs disabled. On an ARM Linux device, the same work stayed strong at higher concurrency, which was one of the reasons for building qaws in the first place.

Large-file checks stayed essentially flat across recent changes and continued to use the platform sendfile path at multi-GB/s throughput. That is the shape I want: small files get a fast cache path, while large files stay on the efficient file-transfer path.

Public source, narrow scope.

Read the code, build it, or use the project as a reference for how I approach small infrastructure tools.

Open repository