Positioning — what engrava is (and isn’t)

engrava is a standalone, in-process database for AI-agent memory. It is built on SQLite and needs no external services. It gives an agent a durable thought-graph with hybrid retrieval (full-text + vector + recency + priority + graph) and an optional tamper-evident journal.

This page explains when engrava is the right tool, when it isn’t, and how it relates to the other memory options you might be choosing between.

When engrava is a good fit

  • You want memory you own and can inspect. The whole store is one SQLite file. You can open it with any SQLite tool, back it up with a file copy (with care around WAL), and query it with SQL when the high-level API isn’t enough.
  • You want retrieval, not just a vector index. engrava fuses FTS5/BM25, vector similarity, recency, priority, and a 1-hop graph signal into one ranked result. See Search.
  • You want a graph, not a flat list. Thoughts are connected by typed, weighted edges, and edges shape retrieval: once dreaming has produced reflections, search pulls their source observations into the candidate pool by default. The 1-hop graph ranking signal is a separate knob and is off until you turn it on. See Configuration → search.
  • You want it in-process. No network hop, no service to operate, no separate process. It runs anywhere Python and SQLite run.
  • You want embeddings to be optional and pluggable. Bring a local model, an OpenAI-compatible endpoint, Ollama, HuggingFace, or your own callback — or run with FTS-only and no embeddings at all. See Configuration → embeddings.
  • Small-to-medium corpora. The default backend keeps vector search simple and inspectable; when corpus size makes brute-force vector search too expensive, switch to the sqlite-vec backend. See Known Limitations.

When engrava is not a good fit

  • You need a managed, horizontally-scaled vector service. engrava is a local, in-process library, not a clustered database. One store is one SQLite file written by one process — two writers on one file is unsupported, not merely contended, see Concurrency. If you need sharding, replication, or a multi-writer service across many machines, use a dedicated vector database.
  • You need more than one process writing the same store. Only one store may write a database file; any number may read it. WAL lets readers and that one writer coexist, and one process can share a store across the async tasks of one event loop — engrava’s own guarded writes there are serialised by a task-reentrant write lock — but two writers on one file is unsupported, not merely contended, and the lock does not reach a read-modify-write your own code spans across two separate calls, or more than one event loop. See Concurrency and Known Limitations → Concurrent Write Safety.
  • You want the library to call an LLM for you. engrava does no LLM-side fact extraction, summarisation, or entity resolution (see Non-goals). It stores and retrieves what you give it; your agent decides what to write.
  • You need retrieval isolation enforced as a security boundary. recall and search_hybrid do take a metadata filters= and a visibility= argument, so you can scope the ranked path to a session, user, or role. But these are query refinements, not access control — they authenticate nothing and are bypassable. For real cross-tenant isolation, use one store per tenant via EngravaManager; for shared-corpus access control, that belongs above engrava.

Non-goals

These are deliberate boundaries, not missing features:

  • No LLM-side intelligence. engrava core and built-in Dreaming do not call a language model. They do no fact extraction, no summarisation, no entity resolution, no semantic contradiction detection, no truth arbitration, and no automatic “memory writing” from raw text. Those belong in your agent (or a downstream extension), above the storage layer. The one consolidation feature that does synthesise — dreaming — is purely structural (clustering + centroids + keyword counts), with no LLM involved. See Evidence and conflicts for the explicit graph pattern available in core. A configured hook (such as memory hygiene’s on_retrieve or decay_function) is your code and may itself call an LLM.
  • Not a distributed system. No clustering, replication, or cross-machine consistency. One file, one writer.
  • Not an application framework. engrava is the memory layer. It does not provide an agent runtime, tool-calling, or prompt orchestration.

How it compares

A rough orientation, not a feature scorecard. Evaluate the specifics against your own workload.

engrava Hosted agent-memory services Framework memory Standalone vector DBs
Deployment In-process library, one SQLite file Typically a hosted/managed service or self-hosted server In-process, tied to the framework Separate database/service (some have embedded modes)
Retrieval model Hybrid: FTS + vector + recency + priority + graph, fused Varies; often vector + recency with managed pipelines Usually buffer/window or a vector-store wrapper Primarily vector similarity (some add keyword/hybrid)
Graph First-class typed/weighted edges; consolidation edges widen the candidate pool by default, the 1-hop graph ranking signal is opt-in Some offer entity/graph memory Generally no Generally no
LLM-side extraction None — you decide what to store Often built in (auto fact-extraction/summarisation) Sometimes, via chains None
External services None required Usually yes Depends on the chosen store Usually a running service
Audit trail Optional tamper-evident thought/edge journal Varies No Generally no
Best for Owning a local, inspectable, hybrid memory graph for an agent Offloading memory ops to a managed pipeline Quick memory inside an existing framework app Large-scale pure vector retrieval

If you are currently using one of these and want concept mappings and porting snippets, see the Migrating from another memory system guide.

See also

  • Search — how the hybrid ranking actually works
  • FAQ — common pre-adoption questions
  • Known Limitations — the hard constraints in one place