deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Kuzu is deprecated: running Graphiti agent memory on one file with LadybugDB and Ollama

A dev.to walkthrough shows how to keep Graphiti agent memory fully local after Kuzu's deprecation: the LadybugDB fork, one graph file, Ollama models, and human approval before any write.

Kuzu is deprecated: running Graphiti agent memory on one file with LadybugDB and Ollama

Kuzu, the embedded graph database, is no longer maintained upstream, and developers who built local graph storage on it need a migration path. A dev.to post by the author of Graphiti Local lays out one: move to LadybugDB, the maintained fork of Kuzu, and run Zep's Graphiti framework for agent memory entirely from a single local file, with Ollama supplying the models instead of an OpenAI key.

What changes with the backend

Graphiti's quickstart assumes a graph database server and a cloud model provider, but for agent memory on one machine both are optional, the post argues. The decision that remains is which embedded file backend to use, and it matters more than it appears because it determines whether reads can continue while new facts are written. Three options are compared: Kuzu itself, which is deprecated and should not be used for new work; FalkorDB Lite, which is maintained but permits a single process per file; and LadybugDB, which allows one read-write open alongside any number of read-only opens — the profile an agent needs when it queries during ingestion.

LadybugDB through the Kuzu driver

Graphiti has no dedicated LadybugDB driver. Because the fork continues Kuzu, it runs through the existing Kuzu driver once the module answers to the old name, via a small alias registered in sys.modules before Graphiti is imported. The post shows a minimal snippet that creates a KuzuDriver pointed at a graph.ladybug file and hands it to Graphiti.

That path has a trap. The Kuzu driver declares full-text indexes, but its index-and-constraint builder does nothing, so the indexes never exist and every hybrid search fails with a Binder exception. The fix is to create them manually on the first read-write open; Graphiti Local's setup command does exactly that and refuses a read-only open when they are missing.

A human approves every write

Rather than fighting the single-writer constraint, the design leans on it. Graphiti Local's MCP server exposes six tools, all of them reads. When an agent learns something, it files a proposal outside the graph file, and nothing touches the graph until a person approves it and a drain command applies the batch. The author's reasoning: a wrong generation can simply be rerun, but a wrong stored entity poisons every later retrieval, and a small local model can confidently extract bad entities from a meeting note. Before version 0.3.0 the server itself held the write lock and blocked other commands from the database; readers now open the file read-only and pick up drained changes without a restart.

Measured on a laptop

According to the post, the setup was last tested in September 2026 with graphiti-core 0.30.1, LadybugDB 0.19, and Ollama running qwen2.5:7b and nomic-embed-text. On an Apple M5 with 32 GiB, excluding model and dependency downloads, database setup took 1.3 seconds, a diagnostic check 0.5 seconds, ingestion 34.4 seconds, a query 1.3 seconds, and approving plus applying an update 44.7 seconds. Retrieval is therefore fast enough for an agent loop, while extraction with a local model is the bottleneck worth batching or running overnight.

The embedder is part of the data

Two silent failures around embeddings are flagged. Vectors from one embedder are not comparable to those from another, even under the same model name: a second Ollama build of nomic-embed-text scored 0.80 cosine against stored vectors where the original scored 1.00, with no error raised, just subtly worse ranking on every search. Dimension width is the second failure mode, since nomic-embed-text returns 768 dimensions rather than the 1536 an OpenAI default assumes. Graphiti Local records which embedder wrote the database and exits if an ingest uses a different one, and its doctor command probes the endpoint and fails when the configured width disagrees.

When an embedded file is the wrong choice

The post names four cases. Multi-user or multi-tenant deployments, since one file is one graph with no enforced boundary between groups; the suggested alternatives are one file per user, or FalkorDB or Neo4j where a real tenant boundary is required. Agents that must write directly, which this design blocks on purpose. Bulk ingestion, where a local model sets the floor on extraction speed. And long-lived dependence on the Kuzu driver, which Graphiti has marked deprecated; Graphiti Local pins graphiti-core for that reason, so the pin should be checked before upgrading.

Why it matters

Kuzu's deprecation left the embedded-graph niche without an obvious successor, and this post shows the fork is close to a drop-in replacement: a module alias and a manual index fix are the whole migration. More broadly, it reframes a concurrency limitation as a safety feature by placing human approval between model extraction and persistent memory, a pattern worth copying wherever agents accumulate knowledge. The caveats are real: the setup rides a driver Graphiti considers deprecated, and embedding portability means switching embedders can quietly degrade search. Graphiti Local is the author's independent open-source project and is not affiliated with or endorsed by Zep.

  • #graph-database
  • #agent-memory
  • #ollama
  • #knowledge-graph
  • #open-source

Related posts