Zero-dependency, header-heavy C++20 execution substrate. An alternative to Apache Arrow on the hot path, built around arena lifetime and branchless kernels; the Arrow C Data Interface is used at egress boundaries.
It builds on Windows out of the box. Point MSVC at the headers and go — no vcpkg, no conan, no protobuf/gRPC/thrift/Boost toolchain, nothing to prebuild. That is the headline: getting Arrow C++ compiling on Windows is a multi-hour, multi-gigabyte ordeal, and Bolt skips it entirely because it is just C++20 standard-library headers.
-
Build cost — the big one. Arrow C++ on Windows pulls in a heavy toolchain (vcpkg, protobuf, gRPC, thrift, Boost) and a long prebuild. Bolt is a collection of C++20 headers that MSVC compiles directly, so it works on Windows out of the box with nothing to install or prebuild.
-
Runtime overhead. Arrow uses
std::shared_ptrfor every Array, Buffer, and RecordBatch — an atomic refcount on every transit. Bolt uses arena allocation + epoch-based lifetime, avoiding that per-transit atomic traffic. -
No mutation path. Arrow buffers are immutable; modifying a column requires a full copy. Bolt uses Venus tick-tock COW: first write copies, all subsequent writes within the epoch are free.
-
No adaptive encoding. Arrow has one physical representation per type. Bolt supports Flat, Constant, Dictionary, Sequence, and View formats. A constant-valued column becomes a single scalar — aggregation is a multiply, not a loop.
-
No inline statistics. Arrow columns carry no min/max or cardinality. Bolt
ColumnStatsenables zone-map skipping, join-strategy selection, and micro-adaptive kernel dispatch.
Bolt is not anti-Arrow. It produces zero-copy Arrow views via the Arrow C Data
Interface (ArrowSchema/ArrowArray) with no libarrow link. Any Arrow consumer
(Polars, DuckDB, Pandas, PyArrow) reads Bolt columns directly. Conversion to the
full Arrow C++ representation is available at I/O boundaries when libarrow is
present.
Bolt is faster than Arrow for the workloads it was designed for: allocation, inter-operator transit, filtering, and constant-column scans. The gains come from the architecture, not from tuning:
- Arena allocation instead of per-buffer malloc. Buffers are bump-allocated from a preallocated arena and freed in one pointer move, so there is no per-allocation malloc/free traffic on the hot path.
- Epoch swaps instead of atomic refcounts. Batches move between operators
by flipping an epoch index rather than incrementing a
shared_ptrrefcount, removing an atomic on every transit. - Selection vectors and constant folding instead of materializing batches. A filter emits a selection vector rather than a new batch, and a constant-valued column collapses a scan into a single scalar operation — both avoid touching every row.
It's early days, and the point above is architectural: these are the reasons Bolt is fast for its target workloads, not a claim about any particular benchmark result.
Headers live under include/bolt/. All are compiled as part of the consumer
build — there is no separate Bolt compile step.
| Header | What it provides |
|---|---|
bolt_types.h |
Type enum, StringView, Schema, Arrow C Data ABI structs |
bolt_arena.h |
Bump allocator (~2.6 ns/alloc), ArenaGuard, tl_arena thread-local |
bolt_arena_ring.h |
Ring-of-arenas for multi-generation scratch allocation |
bolt_channel.h |
Lock-free SPSC/MPSC ring buffers, cache-line padded |
bolt_column.h |
BoltColumn (Flat/Constant/Dict/Seq/View), ColumnStats, BoltBatch COW, BitmapIndex |
bolt_branchless.h |
Filter/aggregate/hash/gather kernels, micro-adaptive dispatch, predicated partition |
bolt_scheduler.h |
TaskRing, TaskPool, WorkerConfig, PhaseBarrier |
bolt_swissmap.h / bolt_hash.h |
SwissTable, swiss_mix, FNV-1a, wyhash |
bolt_ebr.h |
Epoch-Based Reclamation (lock-free snapshot lifetime) |
bolt_disruptor.h |
LMAX-Disruptor-style bounded ring for cross-thread handoff |
bolt_seqlock.h |
Seqlock for read-heavy shared state |
bolt_ribbon.h |
Ribbon filter (compact Bloom alternative) |
bolt_zonemap.h |
Zone-map (min/max block skip) |
bolt_hot_key_cache.h |
Hot-key row cache (bounded, lock-free) |
bolt_lock_free_clock_lru.h |
Clock-hand approximate LRU |
bolt_port.h |
BOLT_RESTRICT, BOLT_FORCE_INLINE, BOLT_PAUSE, etc. |
bolt_topology.h |
CPU topology, core affinity helpers |
bolt_variant_column.h |
Heterogeneous column variant |
bolt_row_view.h |
Zero-copy row view over a BoltBatch |
bolt_work_stealing_deque.h |
Chase-Lev work-stealing deque |
| Directory | What it provides |
|---|---|
ingest/ |
Parquet write (bolt_parquet_write.h), Parquet read (bolt_parquet_read.h), Avro (bolt_avro.h), Roaring bitmap (bolt_roaring.h), CSV, codecs (gzip/lz4/snappy/zstd) |
lakehouse/ |
Delta + Iceberg readers/writers; object stores (local FS, S3, Azure Blob, GCS); parallel scan + scan optimizer; REST catalog fleet: Iceberg REST (OAuth2/SigV4/pagination/multi-table-commit/views/snapshots/branches-tags/stats/vended-creds), Unity Catalog, AWS Glue, Hive Metastore (Thrift), Polaris, Nessie, Gravitino |
crypto/ |
Noise XX (X25519 + ChaCha20-Poly1305), Ed25519 sign/verify/keygen, SigV4 |
net/ |
bolt_tls.h (OpenSSL TLS socket), bolt_http_client.h (outbound HTTP/HTTPS) |
kernels/ |
Numeric, string, temporal, hash, sort, join (Swiss/HashJoin/GroupBy), SIMD, fintech (microstructure, volatility, risk, liquidity, cross-asset) |
parse/ |
fionn JSON parser (bolt::parse) — zero-copy, arena-allocated |
wire/ |
Bolt wire format for cross-process column transport |
stream/ |
Streaming column utilities |
join/ |
Build/probe helpers for hash and sort-merge join |
io/ |
Async I/O primitives |
doc/ |
Document column format |
ybolt/ |
ycpp/Yjs CRDT runtime binding using BoltArenaAllocator (bolt::ybolt) |
Bolt exposes two targets: bolt::bolt (the main static library) and
bolt::ybolt (the ycpp Yjs binding — enabled when extern/ycpp is present).
Guard with if(NOT TARGET bolt::bolt) if more than one component in your build
adds Bolt, so the target is only defined once.
add_subdirectory(extern/bolt)
target_link_libraries(your_target PRIVATE bolt::bolt)Bolt is built as part of any consumer. To build and test standalone:
cmake -S . -B build -DBOLT_BUILD_TESTS=ON -DBOLT_BUILD_BENCHMARKS=ON
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failurePresets: release, debug, msvc, ninja-msvc, clang-cl.
GTest is fetched via FetchContent if not found — the build is self-contained
on Windows without vcpkg.
Every line of code in bolt/ follows these rules:
- No exceptions. All functions are
noexcept. OOM returnsnullptr. - No RTTI. No
dynamic_cast, notypeid, no virtual functions. - No smart pointers. Raw pointers; arena-managed lifetime.
- No
std::string. Fixed-sizechar[64]field names;StringViewfor data. - No
std::vectorin hot structs. Fixed-capacity arrays. - No heap on the hot path. Arena bump allocation only; malloc only at init.
- Cache-line padded atomics. All shared state on separate 64-byte lines.
- Branchless inner loops. Predicated execution, CMOV, SIMD masking.
BOLT_RESTRICTon all kernel parameters. Enables auto-vectorization.- Compile-time type dispatch via X-macros. One runtime switch at the boundary; fully specialized template in the inner loop.
- Pirk et al. "Database Cracking: Fancy Scan, Not Poor Man's Sort!" (DaMoN 2014) — predicated branchless partitioning
- Pirk et al. "CPU and Cache Efficient Management of Memory-Resident DBs" (ICDE 2013) — cache-conscious layouts, prefetch
- Pirk et al. "Voodoo: A Vector Algebra for Portable DB Performance" (VLDB 2016) — composable vector operation algebra
- Mohr-Daurat, Sun, Pirk. "BOSS: Database Kernel Composition" (VLDB 2023) — Arrow-compatible kernel exchange, near-zero overhead
- Pearce, Mohr-Daurat, Pirk. "White-Box Micro-Adaptive Query Processing" (ICDE 2025) — runtime kernel selection on observed selectivity
- Theodorakis et al. "LightSaber: Window Aggregation on Multi-core" (SIGMOD 2020) — parallel aggregation tree with SIMD sub-chunking
- Kersten et al. "Compiled and Vectorized Queries" (VLDB 2018) — vectorized vs compiled: <2× difference, vectorized is simpler
Builds on Windows (MSVC / clang-cl — never MinGW), macOS, and Linux.
No vcpkg, no conan, no external dependencies in the core.
OpenSSL (for net/ and crypto/) is the one accepted external runtime dep.
docs/— design notes, research catalogue, decision log
Bolt was extracted from a set of sibling projects — MarbleDB (storage engine), Chukonu (distributed query engine), BoltAPI (HTTP/WS/SSE framework), and BoltLLM (inference). None of those are publicly available. They are named throughout the docs and in some source comments because they are the workloads that motivated a given design decision; treat those mentions as context for why something is the way it is, not as code you can go and read.
Licensed under the Apache License, Version 2.0.