Tag: Web Servers

  • Zeroserve eBPF web server turns config into code

    Zeroserve eBPF web server turns config into code

    Zeroserve eBPF web server is a new open source HTTPS server that packages a site as one tarball and lets request-handling logic run as sandboxed userspace eBPF. The author positions it as a zero-config alternative to nginx and Caddy for small static sites, scripted middleware, and lightweight gateway work. The interesting part is not that it serves files quickly. It is that the project treats server configuration as a program that can inspect, rewrite, authenticate, rate-limit, and proxy each request.

    The short version

    • Zeroserve serves a website directly from a tar archive, indexes paths to byte ranges on load, and hot-reloads the site, scripts, and TLS material with SIGHUP.
    • Its eBPF scripts run in userspace through an async-ebpf runtime, so the kernel BPF subsystem and CAP_BPF are not part of the normal execution path.
    • The author’s single-core HTTPS benchmarks put Zeroserve ahead of nginx for 174-byte static files, 10 ms eBPF JSON responses, and small proxy responses, while nginx leads on 100 KB proxy responses.
    • The Hacker News thread liked the experiment but kept returning to production risk: hardening, audit history, single-threading, kTLS, and whether code is a better operator interface than config files.
    • The project is easiest to understand as a programmable edge server experiment, not a drop-in replacement for mature web server fleets.

    What happened

    Zeroserve was introduced as a small Rust HTTPS server built around three ideas: one tarball for the site, io_uring for network and disk I/O, and eBPF scripts for request processing. The source repository describes it as a zero-config, fast io_uring-based HTTPS server with built-in TLS, direct tarball serving, hot reload, and low-latency eBPF request middleware.

    The blog post goes further than the README. Any C file under .zeroserve/scripts/ can be compiled into an eBPF object at pack time and run on every request. Those scripts can inspect paths and headers, set response headers, return JSON, rewrite URIs, use metadata in simple HTML substitution, call helpers for SHA-256 and HMAC-SHA256, maintain token-bucket rate limits, sign AWS SigV4 requests, handle OIDC login, or reverse-proxy to an upstream service.

    That design makes Zeroserve feel closer to a tiny programmable gateway than a conventional static server. The tarball model also changes the deployment shape. Nothing is unpacked to disk, so there is no document root full of loose files. A new release can be swapped in as a single archive, then activated with SIGHUP.

    Why Zeroserve eBPF web server is worth watching

    Zeroserve eBPF web server is worth watching because it gives web server configuration a tighter execution model than the usual mix of declarative directives and sidecar scripting. nginx, Caddy, and Apache all have ways to stretch configuration into behavior. Zeroserve makes that move explicit: the eBPF program is the request policy.

    The safety story is also specific. The post says the eBPF bytecode runs inside the server’s own unprivileged userspace process, then gets JIT-compiled through uBPF. A pointer cage confines memory access to the script arena, and a preemption timer can interrupt long-running native code so one bad script does not stall the single event loop. That is a different trade-off from kernel eBPF. Operators get a sandboxed programming model without granting kernel BPF privileges, but they also inherit a young userspace runtime that needs review before serious exposure.

    The benchmark numbers give the project a concrete target. On an 8-core Ryzen 7 3700X, pinned to one core per server, the author reports 36,681 requests per second for a 174-byte static file versus 31,226 for nginx and 12,830 for Caddy. Tuned eBPF dynamic JSON reaches 46,945 requests per second versus 41,231 for nginx Lua in the same write-up. The less flattering number matters too: for a 100 KB proxied response, nginx reports 5,882 requests per second while Zeroserve reports 3,930.

    What does Zeroserve eBPF web server change for builders?

    Zeroserve eBPF web server gives builders a compact way to ship static assets and small request logic together. A documentation site, internal tool, or narrow API gateway could carry its files, headers, authentication checks, template substitutions, and proxy rules in one artifact. For teams that already generate deployable bundles, that is an appealing shape.

    The cost is that operators have to debug behavior as code. A config file can be awkward, but its limits are familiar. A request policy written in C-flavored eBPF can do more, so it can also fail in more interesting ways. Teams would need tests around packaging, script order, metadata keys, hot reload, proxy pooling, and timeout behavior before putting it in front of users.

    The more practical comparison is with nginx plus Lua, Caddy plugins, redbean-style archive servers, and managed static hosting. Zeroserve’s edge is control: local deployment, one archive, programmable request logic, TLS 1.3, HTTP/2, SNI certificate selection, and the transport-security features described by the author. Its weakness is the same control. Most teams choose boring servers because the boring parts have already been burned in. For more infrastructure briefs, see the IT & AI archive.

    What Hacker News readers are arguing about

    The Hacker News discussion was more skeptical than hostile. Several readers liked the single-archive serving model and the idea of moving request behavior into one readable program. Others said they would still choose nginx or Caddy because the benchmark gains were not large enough to offset a newer project’s audit and hardening gap.

    The strongest technical thread focused on the runtime shape. One reader expected a kernel-accelerated web server and asked about multi-process scaling, SO_REUSEPORT, and kTLS. The author replied that forking plus SO_REUSEPORT would be implemented. Another reader questioned whether C scripts are the right operator interface for tasks such as GeoIP, post-TLS request matching, and other common edge behaviors.

    A separate argument had little to do with eBPF and a lot to do with trust. The announcement disclosed AI co-authoring, and some commenters said polished AI-assisted copy makes them more suspicious of whether flags, examples, and benchmarks match the real software. The author responded that critical pieces such as async-ebPF predated current coding agents, that AI assistance was used, and that the author manually checks the output and takes responsibility for it. That exchange is useful because it names the adoption problem plainly: infrastructure tools need trust before they need cleverness.

    Where Zeroserve eBPF fits

    Zeroserve is compelling because it pushes a familiar web-server question into the kernel boundary: how little user-space machinery is needed to serve a small static response path? That makes it interesting for systems programmers, but it also narrows the places where it should be considered.

    Use case Fit Reason
    Learning eBPF networking Strong The project gives a concrete example instead of another packet-filter toy.
    Specialized static response path Possible Latency and kernel-side handling may matter in narrow high-throughput cases.
    General website hosting Weak Nginx, Caddy, and ordinary app servers solve TLS, routing, logs, and operations.
    Security-sensitive production system Careful evaluation needed Kernel-level code changes the failure and audit model.

    The right comparison is not “eBPF versus a web framework.” It is Zeroserve versus the smallest reliable path that already meets the requirement. If the application needs dynamic routing, authentication, observability, and boring maintenance, a conventional server wins. If the goal is to study kernel networking or remove a specific user-space bottleneck, the project becomes much more relevant.

    Teams evaluating this kind of tool should ask three questions before benchmarks: what happens when it fails, who can debug it at 2 a.m., and which operational features have moved out of the usual server layer. Fast code is useful only when the failure path is also understandable.

    The practical read

    Treat Zeroserve as a serious experiment worth testing, not a server to swap into production on a Friday. It has a clean idea: package a site as one archive and run bounded request logic close to the files. That could fit personal sites, internal documentation, static dashboards, test environments, and edge-like gateways where the operator wants tight control without a full application server.

    The first test should be operational rather than synthetic. Build a tarball, add a small script, exercise hot reload, run it behind real TLS, and check how logs, error paths, rate limits, OIDC, proxying, and runaway scripts behave. Then compare the result with a boring nginx or Caddy setup that the team already understands.

    The benchmark claims are a reason to try it, not a reason to trust it. Zeroserve’s best case is small content and small dynamic responses. The HN thread points to the right open questions: audit maturity, script ergonomics, multi-core scaling, kTLS, large proxy bodies, and whether config-as-code helps operators more than it surprises them.

    Sources