defaults < config.json < .env < env < code
(precedence), and can be set from code with
the config API or
cognee-cli config.
Vector database
Thevector section is registered by the vector kind. Backend-specific settings
are registered by the backend’s factory, for example
vector.pgvector. Python flat names are accepted as
aliases, shown in brackets.
Supported providers:
This list is the built-in set, not the set of valid values. Any crate can
register an additional provider under any id on a
ComponentRegistry, and a
binary that injects that registry (ComponentManager::with_registry, or
HandleState::from_settings_with_registry in the bindings) accepts the id in
VECTOR_DB_PROVIDER / GRAPH_DATABASE_PROVIDER — including
Postgres-backed providers, which receive the assembled vector_postgres_url /
graph_postgres_url from the *_HOST / *_PORT / *_NAME / *_USERNAME /
*_PASSWORD settings exactly as the built-ins do, whether or not the
pgvector / pggraph features are compiled in. Registering over a built-in id
replaces it. See
External providers.lancedb— embedded Apache-Arrow / Lance vector store, on disk. The default provider, and default-on incognee,cognee-cliand every binding; requires thelancedbCargo feature (the Arrow/Lance native stack is a large build, so a consumer on another vector store can drop it — and must then setvector_db_providerexplicitly). Unavailable on Android, where its native stack does not cross-compile. The on-disk layout matches the Python SDK’s default LanceDB store, so a Rust deployment can be opened from Python and vice versa.brute-force— pure-Rust in-memory linear scan. Default on Android. Selected on any target by settingvector_db_url = ":memory:".pgvector— Postgres + thepgvectorextension; requires thepgvectorCargo feature on the binary build (default-on incognee-cli). See Pluggable Backends for HNSW indexing andcognee-cli vector-reindex.
vector_db_provider to qdrant is rejected at component
initialization in OSS (it returns a config error rather than falling back).
pgvector index tuning
Thevector.pgvector section, registered by the pgvector factory (pgvector
builds only): four optional overrides for the adapter’s HNSW build, applied per
adapter and clamped to the range shown. Keys are vector.pgvector.hnsw_m,
.hnsw_ef_construction, .maintenance_workers and .maintenance_work_mem_mb,
with aliases pgvector_hnsw_m and so on. Leave them unset unless a
measurement says otherwise: the defaults are calibrated against a 100k-point
corpus of 384-d embeddings, and the two that cost server resources exist so
they can be turned down on a small or shared Postgres without patching the
crate.
m/ef_constructionapply to indexes built after the change. One already on disk keeps the parameters it was built with until it is rebuilt —create_missing_vector_indexes()(cognee-cli vector-reindex) only builds a missing or invalid index, never a valid one — so raisingmon an existing store is aDROP INDEX+ reindex, done deliberately.ef_construction’s floor followsmbecause pgvector requiresef_construction >= 2 × m; no combination of these two can produce aCREATE INDEXthat fails.- Asking for more parallel maintenance workers than the server can start is
not an error. Postgres launches as many as the server’s
max_parallel_workers/max_worker_processesstill allow, down to zero (a serial build). The only cost of over-asking is a slower build, so no server-side configuration is required to adopt the defaults. - Surrounding whitespace in an env value is ignored. A blank, negative or non-numeric env value is ignored and the default applies, as is a value too large for the field’s integer type; an in-type value above the limit clamps. A typo in a deployment environment should not take the store down.
Graph database
Thegraph section is registered by the graph kind; backend sections such as
graph.ladybug are registered by their factory. Python flat names are accepted as
aliases.
Supported providers:
ladybug/kuzu (embedded), postgres (feature pggraph).
As with the vector store, these are the built-ins; an externally registered
provider id is accepted too (see the note under Vector database).
The default is derived from the graph backends the binary was compiled with,
not hardcoded. In order:
ladybug, when that feature is on — every default build;- otherwise
postgres, whenpggraphis on (e.g. a--no-default-features … pggraphimage), however many other ids are registered; - otherwise the single registered backend, when the build has exactly one.
ladybug nor
postgres has to set GRAPH_DATABASE_PROVIDER explicitly.
When Postgres graph credentials are unset they fall back to the relational DB_*
config (see roadmap/cognify-compatibility-plan.md).
Relational database
Therelational section is registered by the relational kind. Backends are
RelationalDbFactorys on the ComponentRegistry, selected by relational.provider
(when that is empty, by the scheme of the resolved URL). An external crate adds a
backend with register_relational, together with its own config sections; it
implements cognee_database::RelationalDb. The built-in SeaORM factory is
registered as sqlite (feature sqlite) and postgres / postgresql (feature
postgres). An unregistered provider is an error.
For
postgres the URL is built from the connection parts; otherwise relational.url
is used verbatim. db_sslmode and single_process stay cognee-wide Settings keys:
the TLS mode is appended to every Postgres URL cognee builds (relational, pgvector
and the Postgres graph), and single_process gates startup recovery.
Single-process startup recovery
single_process / COGNEE_SINGLE_PROCESS asserts that one process owns this
database. In practice it is an opt-in: startup recovery does nothing until you
turn it on. The setting is tri-state:
null restores the derived answer (as for chunk_size). The env var is parsed
by the same code as the config key; a blank or whitespace-only value means
“derive”, not false. The derivation resolves true only for an in-memory
SQLite URL (sqlite::memory:, ?mode=memory) and false for everything else —
Postgres and file-backed SQLite, including the shipped default
sqlite:./cognee.db?mode=rwc. An in-memory database cannot hold a leftover
from a dead run, so the derived true gives the sweep nothing to do.
Which surfaces read it.
The HTTP server never loads the CLI config file and builds no
Settings, so its
environment is the only channel. The CLI runs no sweep on any command: every
invocation is its own process, and two concurrent cognee-cli cognify runs
against one SQLite file are exactly the case the claim exists to catch.
Set it before the first operation. The setting is read once per relational
database per process, on the first operation that opens that database. Flipping
it on afterwards is ignored for the rest of that process’s life (the process may
have live runs a sweep could not tell apart from a dead predecessor’s); a binding
that notices the flip logs a WARN. Restart to recover a dataset that is already
wedged.
What it turns on. Startup recovery for a run killed mid-flight (SIGKILL, an
OOM kill, Android killing the app). A killed run leaves three things behind,
cleared in this order:
- What it had already written into the graph and vector stores, recorded in
the ownership ledger against its
pipeline_run_id— rolled back through the sameRunSweepertheforgetpath uses, scoped strictly to the dead run in its own dataset (artifacts another run also claims are kept); - The
pipeline_runsrow left atStarted— read first by the run gate and never expiring; - The exclusive-run claim on
(dataset, pipeline)— otherwise expiring 24 h later.
cognify_rollback_handler). A rollback that fails is logged and the status row
is retired anyway, so the dataset never wedges permanently. Retiring an orphan
writes a new Errored row in Rust, where Python resets the run to
INITIATED; both resolve to “you may run” at the gate, but a status poller sees
a failed build on Rust versus a never-started run on Python.
Who needs to set it. Any single-process deployment on a file-backed
database: an Android app, a desktop app, a one-process service, a CLI-only setup.
Without it nothing regresses — the claim still ages out after 24 h and the
orphaned row is still cleared by cognee-cli pipeline-unblock --clear or an
HTTP-server restart — but nothing else removes what a killed run wrote. Set it to
false to pin the safe behaviour in a config file.
File storage
Thestorage section is registered by the storage kind. Backends are factories
(StorageFactory) selected by storage.backend; an external crate adds one (an
object store, say) with register_storage.
Only
local (files under data_root_directory) is built in. An unregistered
backend id is an error. No built-in backend reads storage.bucket_name.