From-scratch Rust database with PowQL -- a pipeline query language that reads left to right. No SQL parsing overhead. Compiled predicates. Pure-Rust core.
PowDB vs SQLite on 100K rows. Both engines in memory-mode. All 14 workloads — real numbers, no cherry-picking.
| Workload | PowDB | SQLite | Speedup |
|---|---|---|---|
| agg_min | 236µs | 2.34ms | 9.9x |
| agg_max | 236µs | 2.10ms | 8.9x |
| agg_sum | 231µs | 1.87ms | 8.1x |
| update_by_pk | 55ns | 412ns | 7.5x |
| agg_avg | 401µs | 2.30ms | 5.7x |
| scan_filter_count | 381µs | 1.95ms | 5.1x |
| scan_filter_sort_limit | 2.66ms | 9.77ms | 3.7x |
| update_by_filter | 2.16ms | 6.77ms | 3.1x |
| point_lookup_indexed | 93ns | 282ns | 3.0x |
| multi_col_and_filter | 2.22ms | 4.70ms | 2.1x |
| insert_batch_1k | 238ns | 320ns | 1.3x |
| delete_by_filter | 1.76ms | 2.35ms | 1.3x |
| scan_filter_project_top100 | 9.6µs | 12.7µs | 1.3x |
| point_lookup_nonindexed | 350µs | 432µs | 1.2x |
PowQL reads left to right like a pipeline. No SELECT ... FROM ... WHERE juggling.
Filter and project
SELECT name, price
FROM Product
WHERE price > 10
ORDER BY name;
Product filter .price > 10
order .name
{ .name, .price }
Aggregate with filter
SELECT AVG(age)
FROM User
WHERE city = 'NYC';
avg(User filter .city = "NYC"
{ .age })
Group by with having
SELECT status, COUNT(*)
FROM User
GROUP BY status
HAVING COUNT(*) > 5;
User group .status
having count(*) > 5
{ .status, count(*) }
Insert a row
INSERT INTO User (name, email, age)
VALUES ('Alice', 'alice@example.com', 30);
insert User {
name := "Alice",
email := "alice@example.com",
age := 30
}
Every layer of PowDB is written in Rust, from the storage engine to the query executor.
Filter expressions compile into byte-level operations that skip full row decoding. This is why aggregate and scan workloads run up to 10x faster than SQLite.
Disk-persisted B+ tree indexes in a custom BIDX binary format. Indexed point lookups resolve in under 100ns. Indexes survive restarts and are used automatically.
Write-ahead log with statement-boundary group commit. Full crash recovery via WAL replay, page-zero recovery, and automatic index rebuild.
FNV-1a hashed plan cache with literal substitution. Parse and plan once, execute thousands of times. Prepared queries skip the entire front-end pipeline.
First-class TypeScript client (@zvndev/powdb-client) with a clean async API. Connect to PowDB server over TCP with full type safety.
TLS encryption plus two auth modes: a shared password (POWDB_PASSWORD) or named users with roles (admin / readwrite / readonly, argon2id-hashed) shipped in v0.4.5.
Pure Rust, end to end. No C FFI, no libsqlite3-sys, no bindgen. Single cargo install on any platform Rust supports.
PowQL reads left to right: table, filter, order, limit, project. No inside-out clause structure. Queries read like sentences.
PowDB is pre-1.0 and deliberately scoped. Be honest with yourself before adopting it:
If any of those are dealbreakers, use SQLite -- and we say so plainly in PowDB vs SQLite: when to use which.