Skip to main content

Engraph

Temporal knowledge-graph memory for AI agents — engineered for the lowest retrieval latency.

Engraph is an embedded, Rust-core reimagining of the Graphiti model: raw episodes go in, a bi-temporal knowledge graph of entities and facts comes out, and hybrid search answers queries in microseconds, not hundreds of milliseconds — with no database server, and a fully-local mode that needs no API keys at all.

pip install engraph        # Python (prebuilt wheels)
cargo add engraph-core           # Rust

Why Engraph?

Graphiti popularised the right data model — bi-temporal facts, episodes, entity resolution — but every query pays network round-trips to Neo4j/FalkorDB. Engraph keeps the model and changes the physics:

Engraph Graphiti
Storage Embedded (redb, pure-Rust ACID KV) — single file, no server Neo4j / FalkorDB server required
Vector / lexical / graph indexes In-RAM, in-process (HNSW + BM25 + adjacency) Remote per query
Retrieval latency (10k episodes) p50 ≈ 17 µs, p95 ≈ 1.2 ms (see below) typically tens–hundreds of ms (network + query engine)
Zero-dependency mode Yes — hashing embedder + heuristic extractor, runs offline LLM + embedding API required
Fully-local neural mode fastembed (ONNX) + Ollama via OpenAI-compatible endpoints
Latency toolkit result cache, adaptive planner, latency budgets, stage traces, p50/p95/p99 API —
Similarity floor (min_vector_sim) Yes —
Bi-temporal model, groups/tenancy, communities, MCP server Yes Yes

Latency claims are for Engraph's embedded engine measured on commodity hardware (see Benchmarks); Graphiti figures depend on deployment and network. Different architectures — Engraph optimises for single-node agent memory; a remote graph DB makes sense when many processes share one huge graph.

Benchmarks

Measured with the built-in benchmark (cargo run --release --example bench -- 10000 2000), 10,000 episodes → 14,159 edges / 416 entities, 2,000 random queries, 2 vCPU sandbox, hashing embeddings, Rust 1.97:

search mode p50 p95 p99
hybrid (vector + BM25 + RRF) 17 µs 1.2 ms 1.5 ms
lexical only (BM25) 17 µs 0.4 ms 0.7 ms
vector only (HNSW) 15 µs 0.8 ms 1.0 ms
full (graph expansion + MMR, k=20) 5.9 ms 6.5 ms 7.0 ms
cache hit 18 µs — —

End-to-end from Python (benchmarks/bench_retrieval.py, 2k episodes, includes hashing query embedding + FFI round-trip): hybrid p50 ≈ 70 µs, p95 ≈ 0.7 ms.

Ingestion: ~62 episodes/s (durable, one ACID commit per episode, zero-dep extraction). Cold open: 284 ms (index snapshots). Numbers on your hardware will differ — run the benchmark yourself, and see benchmarks/ for the CI regression harness.

Quickstart

Python — zero dependencies

No API keys, no model downloads: the built-in hashing embedder and heuristic extractor run inside the Rust engine.

from engraph import Engraph

g = Engraph("memory.db")                      # embedded, single file
g.add_episode("intro", "Alice works at Acme Corp. Acme Corp is a robotics company.")
g.add_episode("update", "Alice left Acme and joined Globex.")

res = g.search("Where does Alice work?")
for hit in res["edges"]:
    print(hit["edge"]["fact"], round(hit["score"], 4))

# What did we believe last week? (bi-temporal, transaction-time queries)
old = g.search("Where does Alice work?", as_of=last_week_ms)

# Explain exactly where the microseconds go
res = g.search("Alice", explain=True)
print(res["trace"])     # vector_us, bm25_us, graph_us, fusion_us, fetch_us

Python — fully local, neural quality

from engraph import Engraph, FastEmbedder, OllamaExtractor

g = Engraph(
    "memory.db",
    embedder=FastEmbedder(),        # ONNX embeddings locally (pip install engraph[local])
    extractor=OllamaExtractor(),    # LLM extraction via local Ollama
)

Or with OpenAI (pip install engraph[openai], OPENAI_API_KEY set): OpenAIEmbedder() + OpenAIExtractor().

Rust

use engraph_core::{Engine, EngineConfig, Episode, EpisodeType, SearchConfig, HashingEmbedder};
use engraph_core::types::{now_millis, new_uuid};

let eng = Engine::open(None, EngineConfig::default())?;   // in-memory
eng.ingest_simple(Episode {
    uuid: new_uuid(), tenant_id: "local".into(), group_id: "demo".into(), name: "ep1".into(),
    content: "Alice works at Acme Corp.".into(),
    source: EpisodeType::Text, source_description: "docs".into(),
    reference_time: now_millis(), created_at: now_millis(),
})?;
let hits = eng.search("Alice work", None, &SearchConfig::default())?;

Feature tour

  • Bi-temporal model — every fact carries transaction time (created_at/expired_at) and event time (valid_at/invalid_at). Ask "what is true now?" and "what was true at T?" (as_of, facts_as_of).
  • Hybrid retrieval — vector + BM25 + optional graph expansion, fused with RRF; rerankers: plain RRF, center-node distance (Graphiti-style), MMR diversity.
  • Latency toolkit — result caching, adaptive query planner, per-query latency budgets, stage-level traces (explain=True), rolling p50/p95/p99 via stats().
  • Similarity floor — min_vector_sim drops weak ANN matches for out-of-domain queries.
  • Entity resolution — exact + embedding-similarity merge with configurable threshold; custom labels and attributes.
  • Communities — one-call clustering of the live graph with LLM-updatable names/summaries.
  • Tenancy — group_id partitions everywhere; delete_group() for erasure.
  • MCP server + REST API — bundled, see below.
  • Pluggable everything — embedders/extractors are traits (Rust) and protocols (Python).

MCP server (Claude, Cursor, …)

pip install engraph[mcp]
engraph-mcp --db memory.db          # or: python -m engraph.mcp_server --db memory.db
{ "mcpServers": { "engraph": {
    "command": "engraph-mcp", "args": ["--db", "~/.engraph/memory.db"]
} } }

Tools: add_memory, search_memory, search_facts, get_entity, recent_facts.

REST server

Production deployments use the native HTTP + gRPC server:

cargo run -p engraphd -- --insecure-local --db memory.db
# authenticated deployments: --auth-config grants.json

Native HTTP endpoints are POST /v1/episodes, POST /v1/search, and GET /v1/groups/{tenant}/{group}/submissions/{episode_uuid}. The submission endpoint reports wal_only, queued, recovering, committed, or failed. Equivalent protobuf RPCs are exposed by EngraphService.

The Python/FastAPI server remains a compatibility shim:

pip install engraph[server]
uvicorn engraph.server:app --app-dir python --port 8484
# or ENGRAPH_DB=memory.db python -m engraph.server

POST /episodes · POST /search · GET /nodes/{uuid} · GET /edges/{uuid} · GET /nodes/{uuid}/edges · GET /facts/{group} · GET /stats · DELETE /groups/{group}

Production deployment

  • Container: docker build -t engraphd . (multi-stage, non-root, healthcheck); docker compose up brings up engraphd + Prometheus + Grafana with the provisioning in deploy/.
  • Backups / tiering: engraph export bundles, or engraph tier-out --s3 against any S3-compatible store (AWS/MinIO/R2; build feature s3).
  • Encryption at rest: ENGRAPH_MASTER_KEY (EnvKms) for single-operator setups, or engraphd --vault-kms for HashiCorp Vault Transit with per-tenant derived keys (build feature vault-kms).
  • API keys: engraph hash-key generates a key + argon2 hash for grants.json (example).
  • Runbooks: crash recovery, disk-full, rotation, erasure, restore, upgrade, failover — docs/RUNBOOKS.md.
  • Validation: scripts/load_test.py, scripts/drill_kill_recovery.py, scripts/adversarial_tenant.py, benchmarks/eval_memory.py.
  • Full path to production: docs/PROD.md.

Database migration

v1 uses versioned protobuf records. Existing v0.1 databases must be converted offline:

cargo run -p engraph-cli -- migrate memory.db --output memory.v1.db
# or use --in-place; the original is retained as memory.db.v0.bak

Architecture

flowchart LR
    subgraph Python
        A[add_episode / search] --> P{providers}
        P -->|LLM: OpenAI / Ollama / heuristic| E[extraction JSON]
        P -->|embed: fastembed / OpenAI / hashing| V[vectors]
    end
    subgraph Rust core
        E --> I[ingest pipeline<br/>resolve · dedupe · invalidate]
        V --> I
        I --> S[(redb store<br/>ACID, single file)]
        I --> X[in-RAM indexes<br/>HNSW · BM25 · adjacency]
        Q[query] --> H[hybrid search<br/>vector ∥ BM25 ∥ graph]
        X --> H
        H --> F[RRF · distance · MMR] --> R[top-N hydration]
        S --> R
    end
  • Search never touches the network or the store's read path except to hydrate the final top-N; candidate generation, filtering (group + bi-temporal) and fusion run entirely on RAM indexes.
  • Index snapshots make cold starts ~300 ms at 10k episodes; records are always the source of truth.
  • The LLM is only ever on the ingestion path — retrieval is model-free (unless your query embedder is a model, which can also be the zero-cost hashing one).

Phase 1 correctness and concurrency acceptance results, including reproducible Loom and performance-gate commands, are recorded in docs/PHASE1_VALIDATION.md.

Repo layout

crates/engraph-core    # the embedded engine (pure Rust)
crates/engraph-proto   # durable records and gRPC contracts
crates/engraph-py      # PyO3 bindings (engraph._core)
crates/engraph-cli     # migration and administration CLI
crates/engraphd        # native authenticated HTTP/gRPC server
python/engraph         # Python facade, providers, REST + MCP servers
benchmarks/           # latency harness + CI baseline
tests/                # Rust integration + Python tests

Roadmap

  • Batch ingest API (one group transaction + one view publication)
  • mmap index snapshots (instant open at 1M+ edges)
  • Learned cross-encoder reranker (Python callback)
  • TypeScript bindings (napi-rs)
  • Label-propagation communities with LLM summarisation in one call
  • GraphQL subscriptions / change feed
  • Naming: renamed Engram → Engraph (2026-07-19); engraph free on crates.io + PyPI at rename time — claim before 1.0 (docs/PROD.md)

Contributing

See CONTRIBUTING.md. The latency regression CI runs the benchmark on every PR — treat it as a budget, not a suggestion.

License

Apache-2.0 © Engraph contributors. Not affiliated with Zep Software, Inc.; "Graphiti" refers to their open-source project used here purely as a design reference.

Metadata

Release files for engraph 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for engraph 0.1.0
File Size Uploaded Provenance
engraph-0.1.0.tar.gz 149.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for engraph 0.1.0
File Interpreter ABI Platform
engraph-0.1.0-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details

Total release size: 1.3 MB

Release files / engraph-0.1.0.tar.gz

Download URL engraph-0.1.0.tar.gz
Size 149.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1914f54f5a0675677c2376900a00c89187f6d778621d2d413eb0756a17c5bb4e
BLAKE2b-256 checksum
How to use checksums
243f8e29a44bc66f78b24b79082f0396189a8dabf514698fa34a56f30f2b47b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Release files / engraph-0.1.0-cp39-abi3-win_amd64.whl

Download URL engraph-0.1.0-cp39-abi3-win_amd64.whl
Size 1.1 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
254bde3eaf750d92682b912390632f1be4058bf191d00d0e9b47ac14c8889592
BLAKE2b-256 checksum
How to use checksums
bc15cf8612bbe807e9fd30cae032b60a24c42232db8735a582d197d0678b7fef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Security for engraph 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page