A limit order book achieving 50M+ operations per second with O(1) complexity for all core operations. Built in Zig.
Operation Throughput Latency Complexity
────────────────────────────────────────────────────────
Insert 54.91M ops/sec 18ns O(1)
Cancel 53.11M ops/sec 18ns O(1)
Best Price 211.82M ops/sec 4ns O(1)
Match 119.05M ops/sec 8ns O(1) per fill
Measured on Apple M3 Max.
volt replaces the traditional red-black tree with fixed-size arrays and hierarchical bitsets. Every operation is constant-time.
Price to index mapping:
index = (price - base_tick) / tick_size
Best price discovery uses CPU intrinsics (@clz, @ctz) on the bitset — no tree traversal needed.
| Operation | RB-tree | volt |
|---|---|---|
| Insert | O(log M) | O(1) |
| Cancel | O(log M) | O(1) |
| Best Price | O(1) cached | O(1) bitset |
| Match | O(log M) + O(K) | O(1) + O(K) |
Per side:
Price levels — 1M slots x 32 bytes = 32MB (cache-aligned)
Order pool — 100K pre-allocated orders
HashMap — OrderID -> index, no rehashing
Bitset — 2-level hierarchy for O(1) price discovery
Total: ~64MB per symbol. Pre-allocated, zero allocations in the hot path.
Dynamic allocation introduces latency spikes (malloc can block), cache pollution, and unpredictable HashMap rehashing. Pre-allocation gives deterministic 18ns latency on every operation.
const MatchingEngine = @import("matching_engine");
var engine = try MatchingEngine.init(allocator, .{
.n_ticks = 1_000_000,
.max_orders = 100_000,
.tick_size = 1,
});
defer engine.deinit();
// Insert limit order
const order_id = try engine.insertLimit(.{
.id = unique_id,
.side = .buy,
.price = 45000,
.quantity = 100,
.type = .limit,
.time_in_force = .good_till_cancel,
});
// Cancel
engine.cancel(order_id, .buy);
// Match market order
var events = std.ArrayList(Event).init(allocator);
try engine.matchMarket(.{
.side = .sell,
.quantity = 50,
.events_out = &events,
});Requires Zig 0.14.0+. No external dependencies.
zig build -Doptimize=ReleaseFast # Build
zig build test # Run all tests
zig build bench-ladder-micro # Operation benchmarks
zig build bench-compare # Ladder vs RB-tree comparisonDomain Layer LadderBook (array-based O(1))
OrderBook (RB-tree baseline for comparison)
Application Layer MatchingEngine -> Command Processor -> Event Emitter
Adapter Layer HTTP Server, WebSocket, Binary Protocol
Journal Persistence, Snapshot Store
Testing: unit tests, parity tests (ladder vs RB-tree produce identical results), invariant validation, and performance benchmarks.
No hidden allocations. Comptime metaprogramming for zero-cost abstractions. Direct access to CPU intrinsics. No GC pauses. Simple, readable code.
MIT