Volt is an async I/O runtime for Zig. It provides a work-stealing task scheduler, synchronization primitives, channels, networking, filesystem, timers, and process management — everything you need to build concurrent servers and services, in one package.
Volt brings the same architecture that powers Tokio in Rust to Zig, adapted for Zig’s value semantics and comptime specialization. Zero-allocation waiters, lock-free channels, and O(1) worker waking make it fast. An explicit Io handle (no hidden globals) makes it predictable. It is the I/O counterpart to Blitz (CPU parallelism), the same way Tokio complements Rayon.
LIFO slot + local ring buffer + global injection queue. Cooperative budgeting (128 polls/tick), O(1) bitmap worker waking, and EWMA-based adaptive scheduling. Spawn thousands of tasks across all cores without manual thread management.
Zero-Allocation Primitives
Mutex, RwLock, Semaphore, Barrier, Notify, OnceCell — waiters are embedded directly in futures on the stack. No heap allocation per contended wait. Every primitive offers tryX() (non-blocking, no runtime needed) and x(io) (async, requires runtime).
Lock-Free Channels
MPSC/MPMC (Vyukov ring buffer), Oneshot, Broadcast, Watch, and Select. Bounded channels provide backpressure. 48 B/op total vs 217 B/op in Tokio across channel benchmarks.
Cross-Platform I/O
io_uring (Linux), kqueue (macOS), IOCP (Windows), epoll (fallback) — auto-detected at startup. TCP, UDP, Unix domain sockets, filesystem, process spawning, and signal handling.
Timers and Timeouts
Nanosecond-precision Duration and Instant types. Hierarchical timer wheel, async Sleep, recurring Interval, and Deadline/Timeout combinators. Wrap any operation with a timeout in one line.
Lightweight Tasks
Each task is a state machine at ~256-512 bytes, not a coroutine stack (16-64 KB). Predictable memory, cache-friendly layout, millions of concurrent tasks. Same tradeoff Tokio made — stackless wins where density matters.
Every async primitive provides two access patterns, and they have different runtime requirements:
// Tier 1: No runtime needed -- works anywhere, even in main()
varmutex=volt.sync.Mutex.init();
if (mutex.tryLock()) {
defermutex.unlock();
// critical section
}
// Tier 2: Requires the runtime (volt.run or Io.init)
mutex.lock(io); // blocks this task until acquired
defermutex.unlock();
The tryX() tier (tryLock, tryAcquire, trySend, tryRecv) and all filesystem/networking operations work without starting a runtime. Use them in CLI tools, scripts, or libraries that don’t need async. The convenience tier (mutex.lock(io), ch.send(io, val), sem.acquire(io, n)) requires the io: volt.Io handle — the type system enforces this at compile time, so you can’t accidentally call async APIs without a runtime. See Basic Concepts for the full breakdown.
Overall: Volt wins 16 of 21 benchmarks. Tokio wins 4 (mutex uncontended, OnceCell get, spawn+await, blocking spawn), 1 tie. Memory: 284 B/op total vs Tokio’s 1,868 B/op — 6.6x less. Allocations: 3.0/op vs 17.1/op. Volt’s architecture is derived from Tokio — we would not be here without their work. See Comparing with Tokio for methodology and full results.