.env block: paste it, fill in your LLM API key, install the listed extras, start the listed server, and run the same verification script. Nothing is left to look up on another page.
Before you start:
- Complete Quickstart to understand basic operations
- These blocks change stores only. They assume OpenAI for the LLM and embeddings — to swap those, see LLM Providers, Embedding Providers, or Local Setup for a no-API-key setup
- For per-option depth (tuning, pooling, managed providers), see Relational Databases, Vector Stores, and Graph Stores
When you switch any store — or change embedding model or dimensions — run
cognee.prune.prune_system(metadata=True) once before your next cognify() / remember(). Collections written under the previous embedding dimensions are not compatible with the new ones.What you get by default
With no store variables set at all, Cognee runs entirely on embedded, file-based stores. No server, no extras, nothing to install:SYSTEM_ROOT_DIRECTORY defaults to a folder inside the installed package, which is usually your virtual environment — pin it to an absolute path in your project if you want the stores to survive a reinstall. Because per-dataset isolation is on by default, the graph and vector layers write one file per dataset (<user_id>/<dataset_id>.lbug and .lance.db) rather than the single cognee_graph_ladybug / cognee.lancedb files you get with it switched off.
ladybug and kuzu are the same embedded engine — Ladybug is the renamed Kuzu engine, and either provider value works. They do not share a file: the graph file is named cognee_graph_<provider>, so switching the value points Cognee at a different (initially empty) graph. The exception is upgrades — if a cognee_graph_kuzu file already exists, ladybug keeps using it instead of starting fresh.Choose a stack
The
docker compose commands below come from the docker-compose.yml in the cognee repository — clone it, or point the blocks at your own instances.
The stacks
Embedded (default)
Everything file-based and in-process. This is what you get with no store configuration at all; the block is written out so you can see which variables the other stacks are overriding. Install:One Postgres for everything
Relational metadata, vectors (pgvector), and graph state all in a single Postgres database. Install:pgvector/pgvector:pg17 image on port 5432, with user cognee, password cognee, and database cognee_db already created. Cognee issues CREATE EXTENSION IF NOT EXISTS vector itself, so nothing else needs preparing.
.env configuration:
VECTOR_DB_* and GRAPH_DATABASE_* credentials repeat the relational ones on purpose. Cognee can fall back to DB_* for both layers, but only when multi-user access control is off — with it on (the default), the per-dataset engines need their own explicit values and fail without them. Spelling them out keeps the block working either way.
Postgres and Neo4j
Postgres for metadata and vectors, Neo4j for the graph. This is the usual production shape. Install:neo4j:5.26 with the APOC and GDS plugins enabled, reachable at bolt://localhost:7687 with user neo4j and password pleaseletmein.
.env configuration:
APOC is what gives Cognee’s nodes their type-specific labels in Neo4j Browser. The bundled Docker service includes it; a self-hosted server needs the APOC plugin installed.
neo4j+s:// URI from your Aura console — see Graph Stores → Neo4j Aura (Cloud):
Neo4j graph with embedded rest
Neo4j for the graph, embedded defaults for everything else. The lightest way to get a browsable graph without running Postgres. Install:GRAPH_DATABASE_PASSWORD at your Desktop database’s password, and install APOC from the plugins panel. See Graph Stores → Neo4j Desktop (Local Development).
Turso (libSQL)
All three layers on libSQL. A libSQL file is a SQLite file, so this runs embedded with no server, and the relational layer can later sync against a hosted Turso primary. Install:Remote mode is not available on all three layers. The vector layer accepts a
libsql:// URL with VECTOR_DB_KEY — see Vector Stores → Turso (libSQL) — and the graph layer is local-file only, so setting GRAPH_DATABASE_KEY raises an explicit “not supported yet” error.Verify your stack
Every block above is checked the same way. Save the.env in your project root, then run this from the same directory:
graph_completion answer naming the three stores. If it prints an empty list, or raises before it gets there, work through Troubleshooting below.
To confirm which providers were actually resolved — useful when a variable is not being picked up — print the resolved configuration first:
Mix your own
The five stacks are combinations, not a fixed menu — any relational store works with any vector store and any graph store. These are the values Cognee supports out of the box:
Two rules cover most of what can go wrong when you assemble your own:
- Do not set the
*_DATASET_DATABASE_HANDLERvariables. Cognee derives the per-dataset handler from the provider (pgvector→pgvector,neo4j→neo4j,postgres_demo→postgres_graph,turso→turso_graph). Set them only to pick a different isolation strategy, such aspgvector_sharedandpostgres_graph_shared(one schema per dataset instead of one database per dataset, which needs onlyCREATE SCHEMArights) orneo4j_community. A handler that does not match its provider fails at startup with an explicitEnvironmentError. - Check the combination against access control — see the next section.
neptune (graph) and neptune_analytics (hybrid graph + vector) both need pip install "cognee[neptune]", a neptune-graph:// URL, and AWS credentials from the standard SDK chain. See Graph Stores and Vector Stores for their blocks.
Multi-user access control is on by default
Cognee isolates each dataset in its own database unless you turn that off, which is why several blocks above carry explicit per-layer credentials or anENABLE_BACKEND_ACCESS_CONTROL="false" line. What changes with it on:
Troubleshooting
Neo4jMultiDatabaseSupportError on a Neo4j stack
Neo4jMultiDatabaseSupportError on a Neo4j stack
docker compose --profile neo4j service — allows exactly one database per server, but Cognee’s default access-control mode wants one per dataset. Pick one of:- Turn per-dataset isolation off (what the Neo4j blocks above do):
ENABLE_BACKEND_ACCESS_CONTROL="false". All datasets then share one graph database. - Keep isolation on Community with
GRAPH_DATASET_DATABASE_HANDLER="neo4j_community", which runs one Neo4j container per dataset and needs a reachable Docker daemon. See Neo4j Community handler. - Use Neo4j Enterprise or AuraDB, where
CREATE DATABASEis available and the default mode works unchanged.
Postgres graph store tries to connect to port 123
Postgres graph store tries to connect to port 123
123 is the unset default for GRAPH_DATABASE_PORT. With access control on (the default), the postgres_demo graph store does not inherit the relational DB_* settings — it needs its own credentials. Add the full GRAPH_DATABASE_HOST / PORT / NAME / USERNAME / PASSWORD set, as in the One Postgres block, or set ENABLE_BACKEND_ACCESS_CONTROL="false" to use the fallback.The related warning below is the same mechanism in its working case — the fallback ran, and naming the values explicitly silences it:Empty results, or dimension errors, after switching stores
Empty results, or dimension errors, after switching stores
Vector collections are written for a specific embedding model and dimension count. Switching store, embedding model, or Then re-run your ingestion. Note this deletes everything Cognee has stored — on a shared server, point the new stack at a different database instead.
EMBEDDING_DIMENSIONS leaves collections behind that no longer match, which surfaces as empty recalls or dimension-mismatch errors. Clear them once:Postgres: the database does not exist
Postgres: the database does not exist
Cognee creates its tables, but not the database named in See Relational Databases for the related
DB_NAME — for Postgres that must already exist. The bundled Docker service creates cognee_db for you; on your own server, create it once:DatabaseNotCreatedError case.Running Cognee inside Docker: connection refused
Running Cognee inside Docker: connection refused
localhost inside a container is the container itself. When Cognee runs in a container and the store runs on your host, use host.docker.internal:postgres and neo4j.A variable in .env seems to be ignored
A variable in .env seems to be ignored
Cognee reads
.env from the directory the process starts in, so run your script from the directory holding the file, or set the variables in the process environment instead. Values in .env are applied with override=True, so a .env entry wins over a variable already exported in your shell — if an old exported value is not taking effect, that is why.To see what Cognee actually resolved, print the configuration with the snippet in Verify your stack.Beyond the built-in stores
Qdrant, Redis, Pinecone, Turbopuffer, Milvus, Weaviate, FalkorDB, and Memgraph are available as community-maintained adapters. They install as separate packages and must be registered in your startup code before their provider value works — see Community-Maintained Adapters. If your backend is on neither list, you can write a custom adapter for the vector or graph layer: implement the adapter class and register it in your startup code withuse_vector_adapter("your_name", YourAdapter) or use_graph_adapter(...), and the registered name then works as a VECTOR_DB_PROVIDER / GRAPH_DATABASE_PROVIDER value like any built-in one. With access control on, the adapter also needs its own dataset database handler registered via use_dataset_database_handler(...) — otherwise run it with ENABLE_BACKEND_ACCESS_CONTROL="false". The walkthroughs are Vector Database Integration and Graph Database Integration. The relational layer has no registration hook — it is limited to the built-in sqlite, postgres, and turso.
Relational Databases
Pooling, SSL, managed Postgres, and migration sources
Vector Stores
Per-provider settings, table layout, and subprocess tuning
Graph Stores
Every graph backend, including Neptune and remote Kuzu