# bkndb
[](https://crates.io/crates/bkndb)
[](https://docs.rs/bkndb)
[](https://opensource.org/licenses/Apache-2.0)
**An embedded, zero-daemon hybrid graph-relational database engine with ACID transactions, written in Rust.**
`bkndb` unifies relational tables (with secondary indexes and prefix matching) and a property graph engine into a single storage layer with unified atomic transactions, sub-millisecond graph traversal, and native single-file `.bkndb` container persistence.
Designed for AI agents, GraphRAG, code intelligence tools, local-first applications, and embedded analytics.
---
## Key Features
- **Embedded & In-Process:** Zero network overhead, runs directly inside your application process (like SQLite/libsqlite3).
- **Unified Hybrid ACID Transactions:** Read and write relational rows and property graph nodes/edges in a single atomic transaction with snapshot isolation (`db.write_tx` / `db.read_tx`).
- **High-Performance Native Storage (.bkndb):** Single-file container using an append-only LSM architecture with memory-mapped zero-copy reading (`memmap2`) and MemTable buffering.
- **Sub-Millisecond Graph Traversal:** Built-in BFS shortest path, multi-hop radius traversal (blast radius), in-degree centrality (top hubs), and cascading node deletion.
- **Relational Indexing & Hybrid Join:** Secondary indexing, fast prefix search, and zero-cost joining of graph node traversals with relational metadata tables.
- **High-Volume Bulk Ingestion:** Batch synchronization API (`SyncBatch`) capable of ingesting 100,000+ nodes, edges, and rows in under a second.
- **Zero Heavy Dependencies:** Core uses no heavy C/C++ runtimes.
---
## Performance Highlights
In real-world code intelligence workloads (call graph traversal & AST storage) comparing `bkndb` against SQLite:
| **BFS Shortest Path** (Call Graph) | **81.7 µs** | 2,912.0 µs | **35.6x faster** |
| **Blast Radius / Impact Traversal** | **41.8 µs** | 994.9 µs | **23.8x faster** |
| **AST Batch Sync (10k items)** | **123.4 ms** | 133.2 ms | **1.08x faster** |
---
## Installation
Add `bkndb` to your `Cargo.toml`:
```toml
[dependencies]
bkndb = "0.1"
```
### Feature Flags
| `lsm-backend` | **Yes** | Native single-file `.bkndb` container with zero-copy mmap. |
| `mem-backend` | **Yes** | High-throughput in-memory storage engine. |
| `graph` | **Yes** | Property graph layer (nodes, directed edges, graph algorithms). |
| `relational-layer` | **Yes** | Relational tables, primary keys, secondary indices, and prefix queries. |
| `redb-backend` | No | Optional storage backend powered by `redb`. |
---
## Quick Start
### 1. Basic Graph and Relational Usage
```rust
use bkndb::BknDb;
use bkndb::relational::{RelSchema, ColumnDef, ColumnKind};
use bkndb::value::PropValue;
use bkndb::graph::{Direction, Properties};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. Open or create a persistent database file
let db = BknDb::open("app_data.bkndb")?;
// Or for ephemeral/testing use:
// let db = BknDb::in_memory()?;
// 2. Define a relational schema
let files_schema = RelSchema {
name: "files",
columns: &[
ColumnDef { name: "id", kind: ColumnKind::Int },
ColumnDef { name: "path", kind: ColumnKind::Str },
ColumnDef { name: "hash", kind: ColumnKind::Str },
],
primary_key: "id",
auto_increment_pk: true,
indexed_columns: &["path"],
};
// 3. Atomically write relational rows and graph entities in ONE transaction
db.write_tx(|batch| {
// Relational insert
let mut rel = batch.relational();
let mut props = Properties::new();
props.insert("path".to_string(), PropValue::Str("src/main.rs".to_string()));
props.insert("hash".to_string(), PropValue::Str("a1b2c3d4".to_string()));
let file_pk = rel.table(&files_schema).insert(props)?;
// Graph entities
let mut g = batch.graph();
let mut main_props = Properties::new();
main_props.insert("name".to_string(), PropValue::Str("main".to_string()));
main_props.insert("file_id".to_string(), PropValue::Int(file_pk.as_int().unwrap()));
let main_node = g.create_node("Function", main_props)?;
let mut helper_props = Properties::new();
helper_props.insert("name".to_string(), PropValue::Str("init_config".to_string()));
let helper_node = g.create_node("Function", helper_props)?;
// Directed edge: main() calls init_config()
g.create_edge(main_node, "CALLS", helper_node, Properties::new())?;
Ok(())
})?;
// 4. Query graph traversal
let g = db.graph();
let outgoing = g.neighbors(bkndb::graph::NodeId(1), Direction::Out, Some("CALLS"))?;
println!("Node 1 calls {} function(s)", outgoing.len());
Ok(())
}
```
### 2. Graph Algorithms: Shortest Path & Blast Radius
```rust
use bkndb::BknDb;
use bkndb::graph::{Direction, NodeId};
fn analyze(db: &BknDb, start: NodeId, target: NodeId) -> Result<(), Box<dyn std::error::Error>> {
let g = db.graph();
// BFS shortest path (e.g. call path analysis)
if let Some(path) = g.find_shortest_path(start, target, Direction::Out, Some("CALLS"))? {
println!("Shortest path length: {} hops", path.distance);
for step in path.steps {
println!(" Node {:?} --[{}]--> Node {:?}", step.from, step.edge_type, step.to);
}
}
// Impact / blast radius analysis (traverse up to 3 hops)
let impact = g.traverse_radius(target, Direction::In, 3, Some("CALLS"))?;
println!("Entities impacted by changes to target: {}", impact.len());
Ok(())
}
```
---
## Multi-Language Ecosystem
`bkn-db` also provides bindings for other languages:
- **Python**: `bindings/python/` (supports GraphRAG & AI memory structures)
- **Swift / iOS**: `bindings/bkndb_ffi.swift`
- **Kotlin / Android**: `bindings/uniffi/bkndb_ffi/` (16KB memory page size compliant)
---
## License
Licensed under the Apache License, Version 2.0 ([LICENSE](https://github.com/BknOrg/bkn-db/blob/main/LICENSE) or <http://www.apache.org/licenses/LICENSE-2.0>).