Crystal Graph Engine¶
Crystal is a lightweight, extendable, lightning-fast graph engine written in Go.
It is a property graph database designed for investigation and intelligence mapping (in the spirit of Maltego) and for narrative design (in the spirit of Articy Draft). The core engine has zero external dependencies and ships as a single binary.
Licensed under Apache 2.0 with Commons Clause.
Three ways to run it¶
Crystal exposes the same storage engine through three interfaces — a REST server, a CLI client, and an embeddable Go library.
Authentication is on by default
Crystal refuses to start with authentication enabled and no tokens
configured. This is deliberate: the alternative is a graph database
listening on 0.0.0.0 that anyone with network reach can read, rewrite or
delete. Generate a token first, or set auth.enabled: false explicitly.
Docker¶
The API is then available at http://localhost:7540.
From source¶
go build -o crystal ./cmd/crystal
export CRYSTAL_AUTH_TOKEN=$(openssl rand -hex 32)
./crystal --data-dir ./data --port 7540
CLI¶
go build -o crystal-cli ./cmd/crystal-cli
export CRYSTAL_URL=http://localhost:7540
export CRYSTAL_TOKEN=$CRYSTAL_AUTH_TOKEN
crystal-cli vertex create Person name=Alice age:=30
crystal-cli vertex create Server ip=10.0.0.1
crystal-cli edge create $ALICE_ID $SERVER_ID accessed port:=443
crystal-cli bfs $ALICE_ID --depth 3
crystal-cli export graph.json
As a library¶
import "crystal/pkg/crystal"
db, err := crystal.Open(crystal.Options{
StorageType: "disk",
DataDir: "./mydata",
})
defer db.Close()
ctx := context.Background()
person, _ := db.AddVertex(ctx, "Person", crystal.Properties{"name": "Alice"})
server, _ := db.AddVertex(ctx, "Server", crystal.Properties{"ip": "10.0.0.1"})
db.AddEdge(ctx, person.ID, server.ID, "accessed", crystal.Properties{"port": 443})
Every operation that can do unbounded work takes a context.Context, so a
cancelled request stops the work it started instead of running to completion for
a caller that has gone away.
Know before you deploy¶
Crystal is RAM-resident: the whole graph lives in memory, and disk provides durability rather than capacity. There is no paging and no lazy loading, so the maximum dataset is bounded by RAM, not by disk.
Measured at the benchmark's property density, that is 745 bytes per vertex and 626 bytes per edge, plus roughly 2× for garbage-collector headroom — about 1M vertices / 10M edges on a 16 GB host.
This is a deliberate decision with recorded reasoning and revisit conditions: see ADR 0001 — Storage model.
To scale past one machine, shard by graph and add read replicas — see Cluster Mode.
Documentation¶
- Architecture Overview — layers, data model, concurrency, persistence, transactions
- REST API Reference — every endpoint, with request and response bodies
- CLI Reference —
crystal-clicommands and flags - Query DSL — the fluent query builder
- Embedded Library Guide — using Crystal from Go
- Deployment Guide — Docker, systemd, configuration, security, backup
- Cluster Mode — sharding by graph, read replicas, failover runbook
- Service Levels — durability, consistency, capacity and performance guarantees
- ADR 0001 — Storage model — why Crystal is RAM-resident, and what that costs