Skip to content

Repository files navigation

Basalt logo

Basalt

A from-scratch hybrid OLTP/OLAP (HTAP) database engine — columnar by nature.

Try it live in your browser — no install (runs entirely in WebAssembly)

A from-scratch hybrid OLTP/OLAP (HTAP) database engine in C++17 — with a browser-based Workbench. No external dependencies, ~3k lines, built to be fast and readable. It pairs a row store's point-lookup latency with a columnar engine's scan/aggregate throughput, and every performance claim is benchmarked against SQLite, DuckDB, and MySQL on identical data.

Built in the open as a place to learn how a database actually works — and to make it better together. Contributions welcomeCONTRIBUTING.md.


Highlights

  • Columnar + row hybrid: contiguous native-width columns, per-rowgroup zone maps (granule skipping), dictionary-encoded strings, and a vectorized executor — plus a PK hash index for O(1) point lookups.
  • Disk-backed & persistent: memory-mapped columns, a growable write-through mapping (2.4M inserts/s), and a versioned on-disk catalog.
  • SQL: CREATE/DROP TABLE, INSERT, UPDATE, DELETE, SELECT with WHERE/GROUP BY/aggregates/ORDER BY/LIMIT, INNER/LEFT JOIN (hash join, N-way), CREATE/DROP INDEX (LSM secondary indexes), and a queryable information_schema.
  • Types: BIGINT/INT/DOUBLE/VARCHAR plus BOOLEAN, DATE, TIMESTAMP, exact DECIMAL.
  • Workbench: a local web client with a syntax-highlighted SQL editor (line numbers, autocomplete, Format, history), an object tree with per-table Browse / Structure / Insert / Drop actions, a Structure/DDL view, an editable result grid (inline edit / add / delete rows → generated SQL, resizable columns, cell peek, sort, filter), query-plan view, resizable panels, CSV/JSON export, benchmark templates, and light/dark. Runs natively or entirely in-browser via WASM. See WORKBENCH.md.
  • Honest benchmarks: beats SQLite 13–70× and MySQL 16–63× on analytics, wins/ties single-threaded DuckDB on most queries, and documents where it loses and why.

The Workbench

A dependency-free, browser-based SQL client — syntax-highlighted editor, object tree, editable result grid, query plans, and a Structure/DDL view. Try it live (runs entirely in WebAssembly — the screenshots below are the actual playground):

Basalt Workbench — SQL editor and result grid

Query plan view Table structure & DDL view

Docs: Usage guide · Benchmarks · transactional/peak-load analysis · Workbench · ROADMAP (what we want to build next, vs each existing DB).

History: Basalt began as a smaller in-memory engine ("v1"). That prototype has been retired — the disk-backed engine here is the mainstream project. The original is preserved at the v1-final git tag.


Setup

Platform: Linux or macOS (uses POSIX mmap + sockets; not Windows — use WSL).

Prerequisites

  • A C++17 compiler (clang++ or g++) and make.
  • SQLite dev headersonly needed for the benchmark binary (basalt-bench), which links -lsqlite3. The CLI and Workbench don't need it.
  • (optional) Python 3 + pip install duckdb pymysql for the DuckDB/MySQL comparison scripts.
# macOS: compiler ships with Xcode Command Line Tools; SQLite is in the SDK
xcode-select --install                       # if not already installed

# Debian/Ubuntu:
sudo apt-get install -y build-essential libsqlite3-dev

Clone

git clone https://github.com/basalt-db/basalt.git
cd basalt

Quickstart

make                              # builds: basalt (CLI), basalt-server, basalt-bench
# just the CLI + Workbench (no SQLite needed):  make basalt basalt-server
./basalt mydb                     # persistent SQL REPL on directory ./mydb
./basalt-server demo_root 8090    # Workbench → open http://127.0.0.1:8090

The Workbench starts empty on a fresh clone — click + New DB (or run CREATE DATABASE …) to make one, then CREATE TABLE …. Point basalt-server at any directory of Basalt databases. To explore real data, load the IMDb datasets with basalt-import (see docs/USAGE.md).

CREATE TABLE users (id BIGINT PRIMARY KEY, name VARCHAR, tier INT);
INSERT INTO users VALUES (1,'alice',1),(2,'bob',2);
CREATE INDEX u_tier ON users(tier);
SELECT tier, COUNT(*) FROM users GROUP BY tier;

Browser playground (WebAssembly)

No compiler needed — the engine compiles to WASM and the Workbench runs entirely in your browser: https://basalt-db.github.io/basalt/. Rebuild it locally with ./build_wasm.sh (uses the emscripten Docker image) then serve web/.

Try it on real data

The importer loads the public IMDb datasets (~12.6M rows) so you can explore joins, indexes, and the query planner on something real — see docs/USAGE.md.


Use it from your app

Official clients let you talk to Basalt from your own code — embedded (no server) or over HTTP. See clients/ for the overview and HTTP API.

JavaScript / TypeScriptbasaltdb (npm) · repo basalt-db/basalt-js — runs the engine embedded in-process via WebAssembly (Node & browser, like sql.js) or against a server:

import { Basalt } from 'basaltdb';           // npm install basaltdb
const db = await Basalt.create();            // in-memory, no server
db.exec("CREATE TABLE t (id BIGINT PRIMARY KEY, name VARCHAR)");
db.table('t').insert({ id: 1, name: 'alice' });
db.query('SELECT * FROM t');                 // [{ id: 1, name: 'alice' }]

Pythonbasalt-client (PyPI) · repo basalt-db/basalt-python — dependency-free DB-API 2.0-style client over HTTP:

import basalt                                 # pip install basalt-client
con = basalt.connect("http://127.0.0.1:8090", database="mydb")
con.query("SELECT tier, COUNT(*) FROM users GROUP BY tier")

Any language — the server exposes a tiny HTTP/JSON API (POST /api/query, GET /api/schema, …). ORM dialects (Prisma/SQLAlchemy/…) are on the roadmap, gated on transactions + a Postgres wire protocol — see clients/README.md for the honest status.


Benchmarks at a glance

5M-row analytical workload, single-threaded, Apple M1 Pro (full methodology in the benchmark docs — the numbers include honest caveats about in-process vs client-server and durability):

Query Basalt SQLite MySQL 8.0 DuckDB (1 core)
COUNT(*) 0.0008 ms 3.8 ms 66 ms 0.46 ms
filtered SUM 12.8 ms 173 ms 506 ms 4.7 ms
GROUP BY rollup 25 ms 1789 ms 978 ms 27 ms
indexed WHERE id = ? 0.0034 ms 0.011 ms 0.5 ms 0.17 ms

See BENCHMARKS.md and BENCHMARKS.md.


Architecture (one screen)

SQL ─▶ tokenizer + recursive-descent parser ─▶ AST
        │
        ▼
   vectorized executor           storage engine (per table)
   • zone-map rowgroup skip      • columns = mmap'd native-width buffers
   • columnar mask filter        • zone maps (min/max per 64Ki-row group)
   • fused filter+aggregate      • string dictionary (→ int32 id)
   • hash / direct-map GROUP BY  • PK hash index (O(1) point lookup)
   • hash JOIN (N-way)           • LSM secondary indexes (sorted run + delta)

The single-table path is vectorized and column-at-a-time; joins use hash joins. Reads are lock-shared (concurrent); writes are single-writer. See ROADMAP.md for what's next (vectorized joins, MVCC, compression…).


Contributing

This is a community project — issues, discussions, and PRs are all welcome, whether it's a bug fix, a new operator, a benchmark, docs, or one of the roadmap items. Start with CONTRIBUTING.md and our Code of Conduct.

License

MIT — do anything, no warranty.

About

Basalt — a from-scratch hybrid OLTP/OLAP (HTAP) database engine in C++17, columnar by nature, with a browser Workbench and WASM playground; benchmarked vs SQLite, DuckDB, and MySQL

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages