FIELD NOTE · November 30, 2025 · 6 min read

Why WDBX Is Written in Zig

Garbage collection pauses are invisible in the mean and fatal in the tail. WDBX is Zig because a real-time vector database is a p99 product, not a p50 product.

By MLAI Runtime Engineering

Every database benchmark leads with average latency, and average latency is the least interesting number in the file. Users don't experience the mean — they experience the worst request of their session. A vector store backing real-time inference is a p99 product, and the p99 is where garbage collectors live.

The case against the GC

A GC pause is a latency spike you didn't schedule, can't fully predict, and pay at the worst time — under memory pressure, which is to say under load. Java and Go runtimes have spent decades engineering the pause down, and the engineering is genuinely impressive. But small-and-unpredictable still loses to zero-and-deterministic when the SLA is single-digit milliseconds.

Zig gives us manual, deterministic memory management with allocator discipline the language actually enforces — every allocation site names its allocator, every structure owns its lifetime. The p99 stays glued to the mean because nothing runs that we didn't write.

Comptime is the quiet superpower

Zig executes code at compile time, which for a vector engine means hot paths can be specialized before they ship. Distance kernels, lookup tables, and SIMD choices should be tied to the build target and verified in source rather than implied by marketing copy.

database/kernel.zig
// dimension-specialized at compile time — no runtime branching
pub fn CosineKernel(comptime dim: usize) type {
    return struct {
        pub fn dot(a: *const [dim]f32, b: *const [dim]f32) f32 {
            var acc: @Vector(8, f32) = @splat(0);
            comptime var i: usize = 0;
            inline while (i < dim) : (i += 8) {
                const va: @Vector(8, f32) = a[i..][0..8].*;
                const vb: @Vector(8, f32) = b[i..][0..8].*;
                acc += va * vb;
            }
            return @reduce(.Add, acc);
        }
    };
}

And because Zig speaks C natively, the boundary to BLAS, Metal, and CUDA kernels costs nothing. We get the ecosystem without the FFI tax.

The honest tradeoff: dev-channel Zig churns, and we pay a migration tax roughly twice a year. We pay it gladly — the alternative is paying a GC tax on every request, forever.

Language choices are bets about what a system will be punished for. WDBX will be punished for tail latency. So we chose the language with nothing in the tail.