CozoDB

An embeddable, transactional, relational-graph database with Datalog as its query language — designed for algorithm-heavy and graph-centric workloads.

CozoDB is a transactional, relational-graph database written in Rust that uses Datalog as its query language. It can be embedded directly into your application (like SQLite), run as a standalone server, or used via WASM in the browser. Its key differentiator is bringing the expressive power of Datalog — recursive queries, graph traversals, and algorithm primitives — to a practical, embeddable database.

Features

  • Datalog query language — a declarative logic programming language well-suited to graph traversal, recursive queries, and constraint solving; more expressive than SQL for many graph workloads
  • Relational + graph in one — stores data in regular relations (like SQL tables) but queries can traverse graph edges naturally without JOIN soup
  • Embeddable — runs in-process as a Rust library, Python library, Node.js module, or WASM module; no separate server required
  • ACID transactions — full transactional guarantees backed by a choice of storage engines
  • Multiple storage backends — in-memory, RocksDB (persistent), SQLite, TiKV (distributed)
  • Built-in algorithms — shortest path, PageRank, community detection, and other graph algorithms available as first-class query primitives, not afterthoughts
  • Fixed rules — define reusable recursive computations (e.g. transitive closure, BFS/DFS) that compose with regular Datalog rules
  • Multi-language — official bindings for Rust, Python, Node.js, Java, C, and WASM/browser

Installation

As a standalone server

cargo install cozo-bin

Or download a pre-built binary from the releases page:

# Start the server (HTTP API on port 9070 by default)
cozo-bin server
# Debian / Fedora — install via cargo or Docker (see above). Docker works on all Linux distributions.

As a Rust library

cargo add cozo

Python

pip install pycozo

Node.js

npm install cozo-node

The Query Language: CozoScript

CozoScript is a dialect of Datalog. Queries are structured as rules — named Horn clauses that derive new facts from existing ones.

Basic queries

# Define a relation and query it
?[name, age] := *person[name, age], age > 30

# Equivalent to: SELECT name, age FROM person WHERE age > 30

Graph traversal

# Find all friends of Alice (one hop)
?[friend] := *knows[{from: "Alice", to: friend}]

# Find all people reachable from Alice (transitive closure)
reachable[from, to] := *knows[{from: from, to: to}]
reachable[from, to] := reachable[from, mid], *knows[{from: mid, to: to}]

?[person] := reachable["Alice", person]

Built-in graph algorithms

# Shortest path between two nodes
?[path, cost] <~ ShortestPathDijkstra(*road[], "CityA", "CityB")

# PageRank over a graph relation
?[node, rank] <~ PageRank(*links[])

# Connected components
?[node, component] <~ ConnectedComponents(*edges[])

# Betweenness centrality
?[node, centrality] <~ BetweennessCentrality(*edges[])

Mutations

# Insert rows
:put person {name: "Alice", age: 30}
:put person {name: "Bob", age: 25}

# Insert a relationship
:put knows {from: "Alice", to: "Bob"}

# Delete
:rm person {name: "Bob"}

Using CozoDB from Rust

use cozo::{DbInstance, DataValue, ScriptMutability};

fn main() -> cozo::Result<()> {
    // Open an in-memory database
    let db = DbInstance::new("mem", "", Default::default())?;

    // Create a relation
    db.run_script(
        ":create person {name: String => age: Int}",
        Default::default(),
        ScriptMutability::Mutable,
    )?;

    // Insert data
    db.run_script(
        r#"?[name, age] <- [["Alice", 30], ["Bob", 25]]
           :put person {name => age}"#,
        Default::default(),
        ScriptMutability::Mutable,
    )?;

    // Query
    let result = db.run_script(
        "?[name, age] := *person[name, age], age > 20",
        Default::default(),
        ScriptMutability::Immutable,
    )?;

    println!("{:?}", result.rows);
    Ok(())
}

HTTP API (standalone server mode)

When running as a server, CozoDB exposes a simple HTTP API:

# Run a query
curl -X POST http://localhost:9070/text-query \
  -H 'Content-Type: application/json' \
  -d '{
    "script": "?[name, age] := *person[name, age]",
    "params": {}
  }'

When to use CozoDB

CozoDB is the right choice when:

  • Your data is naturally graph-shaped (social networks, knowledge graphs, dependency trees, routing)
  • You need recursive queries (transitive closure, BFS/DFS, hierarchical data) that are painful to express in SQL
  • You want graph algorithms (PageRank, shortest path, community detection) without an external graph processing system
  • You want an embeddable database with these capabilities — not a separate graph database server
  • You are building a knowledge base, recommendation engine, or rule-based reasoning system

For purely relational workloads without graph traversal, a traditional SQL database is likely a better fit.