> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Store Configurations

> Copy-paste .env blocks for the supported relational, vector, and graph store combinations.

Cognee keeps memory in three stores: a **relational** database for metadata, a **vector** store for embeddings, and a **graph** store for entities and their relationships. Each is configured on its own, so a working setup is always a *combination* — and the combination is what the reference pages leave to you to assemble.

This page closes that gap. Every stack below is one complete `.env` block: paste it, fill in your LLM API key, install the listed extras, start the listed server, and run the same [verification script](#verify-your-stack). Nothing is left to look up on another page.

**Before you start:**

* Complete [Quickstart](/getting-started/quickstart) to understand basic operations
* These blocks change **stores only**. They assume OpenAI for the LLM and embeddings — to swap those, see [LLM Providers](/setup-configuration/llm-providers), [Embedding Providers](/setup-configuration/embedding-providers), or [Local Setup](/guides/local-setup) for a no-API-key setup
* For per-option depth (tuning, pooling, managed providers), see [Relational Databases](/setup-configuration/relational-databases), [Vector Stores](/setup-configuration/vector-stores), and [Graph Stores](/setup-configuration/graph-stores)

<Info>
  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.
</Info>

## 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:

| Layer      | Default | Variable                  | Where it lives                                |
| ---------- | ------- | ------------------------- | --------------------------------------------- |
| Relational | SQLite  | `DB_PROVIDER`             | `<SYSTEM_ROOT_DIRECTORY>/databases/cognee_db` |
| Vector     | LanceDB | `VECTOR_DB_PROVIDER`      | `<SYSTEM_ROOT_DIRECTORY>/databases/`          |
| Graph      | Ladybug | `GRAPH_DATABASE_PROVIDER` | `<SYSTEM_ROOT_DIRECTORY>/databases/`          |

`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](#multi-user-access-control-is-on-by-default) 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.

<Note>
  `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.
</Note>

## Choose a stack

| Stack                                              | Servers to run        | Extras to install                              | Good for                                                           |
| -------------------------------------------------- | --------------------- | ---------------------------------------------- | ------------------------------------------------------------------ |
| [Embedded](#embedded-default)                      | none                  | none                                           | Local development, single process, getting started                 |
| [One Postgres](#one-postgres-for-everything)       | Postgres              | `postgres`                                     | One managed service for the whole memory layer                     |
| [Postgres and Neo4j](#postgres-and-neo4j)          | Postgres, Neo4j       | `postgres`, `neo4j`                            | Production shape: graph-native graph store, Postgres for the rest  |
| [Neo4j only](#neo4j-graph-with-embedded-rest)      | Neo4j                 | `neo4j`                                        | Inspecting the graph in Neo4j Browser without standing up Postgres |
| [Turso](#turso-libsql)                             | none (or Turso cloud) | `turso`                                        | A SQLite-compatible stack with a hosted option                     |
| [Custom or community](#beyond-the-built-in-stores) | your backend's        | none — a separate package, or your own adapter | Qdrant, Redis, Memgraph, and other backends core does not ship     |

The `docker compose` commands below come from the `docker-compose.yml` in the [cognee repository](https://github.com/topoteretes/cognee) — 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:**

```bash theme={null}
pip install cognee
```

**Servers:** none.

**.env configuration:**

```dotenv theme={null}
# LLM (see /setup-configuration/llm-providers to change provider)
LLM_API_KEY="your_api_key"

# Relational — SQLite (embedded)
DB_PROVIDER="sqlite"
DB_NAME="cognee_db"

# Vector — LanceDB (embedded)
VECTOR_DB_PROVIDER="lancedb"

# Graph — Ladybug (embedded)
GRAPH_DATABASE_PROVIDER="ladybug"

# Optional: pin storage to your project instead of the install directory
# SYSTEM_ROOT_DIRECTORY="/absolute/path/to/project/.cognee_system"
# DATA_ROOT_DIRECTORY="/absolute/path/to/project/.data_storage"
```

<Warning>
  The embedded graph store uses file-based locking and is not meant to be shared between processes or agents running at once. For concurrent access, use Neo4j or the Postgres graph store below.
</Warning>

### One Postgres for everything

Relational metadata, vectors (pgvector), and graph state all in a single Postgres database.

**Install:**

```bash theme={null}
pip install "cognee[postgres]"
# or, to avoid building psycopg2 from source:
pip install "cognee[postgres-binary]"
```

**Server:**

```bash theme={null}
docker compose --profile postgres up -d postgres
```

The bundled service is the `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:**

```dotenv theme={null}
# LLM
LLM_API_KEY="your_api_key"

# Relational — Postgres
DB_PROVIDER="postgres"
DB_NAME="cognee_db"
DB_HOST="127.0.0.1"
DB_PORT="5432"
DB_USERNAME="cognee"
DB_PASSWORD="cognee"

# Vector — pgvector, in the same database
VECTOR_DB_PROVIDER="pgvector"
VECTOR_DB_NAME="cognee_db"
VECTOR_DB_HOST="127.0.0.1"
VECTOR_DB_PORT="5432"
VECTOR_DB_USERNAME="cognee"
VECTOR_DB_PASSWORD="cognee"

# Graph — Postgres tables, in the same database (demo, see the warning below)
GRAPH_DATABASE_PROVIDER="postgres_demo"
GRAPH_DATABASE_NAME="cognee_db"
GRAPH_DATABASE_HOST="127.0.0.1"
GRAPH_DATABASE_PORT="5432"
GRAPH_DATABASE_USERNAME="cognee"
GRAPH_DATABASE_PASSWORD="cognee"
```

<Warning>
  The Postgres **graph** store is a demo feature — it stores nodes and edges in `graph_node` / `graph_edge` tables and does not support the Cypher search types. Postgres remains a good production choice for the relational and vector layers; for the graph layer in production use Neo4j (next stack) or the licensed Postgres graph adapter — book a call at [cognee.ai](https://www.cognee.ai). See [Graph Stores](/setup-configuration/graph-stores) → *Postgres*.
</Warning>

The `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](#multi-user-access-control-is-on-by-default) 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:**

```bash theme={null}
pip install "cognee[postgres,neo4j]"
```

**Servers:**

```bash theme={null}
docker compose --profile postgres up -d postgres
docker compose --profile neo4j up -d neo4j
```

The bundled Neo4j service is `neo4j:5.26` with the APOC and GDS plugins enabled, reachable at `bolt://localhost:7687` with user `neo4j` and password `pleaseletmein`.

**.env configuration:**

```dotenv theme={null}
# LLM
LLM_API_KEY="your_api_key"

# Relational — Postgres
DB_PROVIDER="postgres"
DB_NAME="cognee_db"
DB_HOST="127.0.0.1"
DB_PORT="5432"
DB_USERNAME="cognee"
DB_PASSWORD="cognee"

# Vector — pgvector, in the same Postgres database
VECTOR_DB_PROVIDER="pgvector"
VECTOR_DB_NAME="cognee_db"
VECTOR_DB_HOST="127.0.0.1"
VECTOR_DB_PORT="5432"
VECTOR_DB_USERNAME="cognee"
VECTOR_DB_PASSWORD="cognee"

# Graph — Neo4j
GRAPH_DATABASE_PROVIDER="neo4j"
GRAPH_DATABASE_URL="bolt://localhost:7687"
GRAPH_DATABASE_NAME="neo4j"
GRAPH_DATABASE_USERNAME="neo4j"
GRAPH_DATABASE_PASSWORD="pleaseletmein"

# Required on Neo4j Community, which allows only one database per server.
# Drop this line on Neo4j Enterprise or AuraDB to keep per-dataset isolation.
ENABLE_BACKEND_ACCESS_CONTROL="false"
```

<Note>
  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](https://neo4j.com/docs/apoc/current/installation/) installed.
</Note>

For **Neo4j AuraDB**, keep everything above and swap the connection line for the `neo4j+s://` URI from your Aura console — see [Graph Stores](/setup-configuration/graph-stores) → *Neo4j Aura (Cloud)*:

```dotenv theme={null}
GRAPH_DATABASE_URL="neo4j+s://<your-instance-id>.databases.neo4j.io"
GRAPH_DATABASE_PASSWORD="<your-aura-password>"
```

### 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:**

```bash theme={null}
pip install "cognee[neo4j]"
```

**Server:**

```bash theme={null}
docker compose --profile neo4j up -d neo4j
```

**.env configuration:**

```dotenv theme={null}
# LLM
LLM_API_KEY="your_api_key"

# Relational — SQLite (embedded)
DB_PROVIDER="sqlite"
DB_NAME="cognee_db"

# Vector — LanceDB (embedded)
VECTOR_DB_PROVIDER="lancedb"

# Graph — Neo4j
GRAPH_DATABASE_PROVIDER="neo4j"
GRAPH_DATABASE_URL="bolt://localhost:7687"
GRAPH_DATABASE_NAME="neo4j"
GRAPH_DATABASE_USERNAME="neo4j"
GRAPH_DATABASE_PASSWORD="pleaseletmein"

# Required on Neo4j Community, which allows only one database per server.
# Drop this line on Neo4j Enterprise or AuraDB to keep per-dataset isolation.
ENABLE_BACKEND_ACCESS_CONTROL="false"
```

Once a run finishes, open [http://localhost:7474](http://localhost:7474), log in with the same credentials, and inspect the graph. Neo4j Desktop works the same way — point `GRAPH_DATABASE_PASSWORD` at your Desktop database's password, and install APOC from the plugins panel. See [Graph Stores](/setup-configuration/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:**

```bash theme={null}
pip install "cognee[turso]"
```

**Servers:** none for the embedded setup.

**.env configuration:**

```dotenv theme={null}
# LLM
LLM_API_KEY="your_api_key"

# Relational — libSQL file (drop-in for SQLite)
DB_PROVIDER="turso"
DB_NAME="cognee_db"

# Vector — libSQL file
VECTOR_DB_PROVIDER="turso"
VECTOR_DB_URL="/absolute/path/to/cognee.turso.db"

# Graph — libSQL file (defaults under the system databases directory)
GRAPH_DATABASE_PROVIDER="turso"
# GRAPH_DATABASE_URL="/absolute/path/to/graph.db"
```

To point the **relational** layer at a hosted Turso database, add the remote credentials — Cognee then reads and writes a local replica and syncs it in the background:

```dotenv theme={null}
DB_TURSO_URL="libsql://<your-db>.turso.io"
DB_TURSO_AUTH_TOKEN="<your-token>"
```

<Note>
  Remote mode is not available on all three layers. The vector layer accepts a `libsql://` URL with `VECTOR_DB_KEY` — see [Vector Stores](/setup-configuration/vector-stores) → *Turso (libSQL)* — and the graph layer is local-file only, so setting `GRAPH_DATABASE_KEY` raises an explicit "not supported yet" error.
</Note>

## 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:

```python theme={null}
import asyncio

import cognee


async def main():
    # Clear anything written under a previous store or embedding configuration
    await cognee.prune.prune_data()
    await cognee.prune.prune_system(metadata=True)

    await cognee.remember(
        [
            "Cognee keeps memory in three stores: a relational database for metadata, "
            "a vector store for embeddings, and a graph store for entities and their relationships."
        ],
        dataset_name="store_config_check",
    )

    print(await cognee.recall(query_text="Which stores does cognee keep memory in?"))


asyncio.run(main())
```

A working stack prints a `graph_completion` answer naming the three stores. If it prints an empty list, or raises before it gets there, work through [Troubleshooting](#troubleshooting) below.

To confirm *which* providers were actually resolved — useful when a variable is not being picked up — print the resolved configuration first:

```python theme={null}
from cognee.infrastructure.databases.relational import get_relational_config
from cognee.infrastructure.databases.vector.config import get_vectordb_config
from cognee.infrastructure.databases.graph.config import get_graph_config

print(get_relational_config().db_provider)
print(get_vectordb_config().vector_db_provider)
print(get_graph_config().graph_database_provider)
```

## 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:

| Layer      | Variable                  | Built-in values                                                                                                                 | Extra required                                              |
| ---------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Relational | `DB_PROVIDER`             | `sqlite` (default), `postgres`, `turso`                                                                                         | `postgres` / `postgres-binary`, `turso`                     |
| Vector     | `VECTOR_DB_PROVIDER`      | `lancedb` (default), `pgvector`, `turso`, `neptune_analytics`                                                                   | `postgres` / `postgres-binary`, `turso`, `neptune`          |
| Graph      | `GRAPH_DATABASE_PROVIDER` | `ladybug` (default), `kuzu`, `ladybug-remote`, `kuzu-remote`, `neo4j`, `postgres_demo`, `turso`, `neptune`, `neptune_analytics` | `neo4j`, `postgres` / `postgres-binary`, `turso`, `neptune` |

Two rules cover most of what can go wrong when you assemble your own:

* **Do not set the `*_DATASET_DATABASE_HANDLER` variables.** 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 as `pgvector_shared` and `postgres_graph_shared` (one schema per dataset instead of one database per dataset, which needs only `CREATE SCHEMA` rights) or `neo4j_community`. A handler that does not match its provider fails at startup with an explicit `EnvironmentError`.
* **Check the combination against access control** — see the next section.

The AWS options are the ones not shown as a stack above: `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](/setup-configuration/graph-stores) and [Vector Stores](/setup-configuration/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 an `ENABLE_BACKEND_ACCESS_CONTROL="false"` line. What changes with it on:

| Store                                             | With access control on (default)                                                 | With `ENABLE_BACKEND_ACCESS_CONTROL="false"`                |
| ------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| pgvector                                          | Needs explicit `VECTOR_DB_HOST` / `PORT` / `NAME` / `USERNAME` / `PASSWORD`      | Falls back to the relational `DB_*` values                  |
| `postgres_demo` graph                             | Needs explicit `GRAPH_DATABASE_HOST` / `PORT` / `NAME` / `USERNAME` / `PASSWORD` | Falls back to the relational `DB_*` values (logs a warning) |
| Neo4j                                             | Creates one database per dataset — Enterprise or AuraDB only                     | All datasets share the one graph database                   |
| Embedded graph and vector (Ladybug/Kuzu, LanceDB) | One file per dataset, under a per-user directory                                 | One shared file each                                        |
| SQLite                                            | One shared file either way                                                       | One shared file either way                                  |

## Troubleshooting

<AccordionGroup>
  <Accordion title="Neo4jMultiDatabaseSupportError on a Neo4j stack">
    ```text theme={null}
    The configured Neo4j server reports the 'community' edition, which supports only a
    single database. Per-dataset graph isolation on Neo4j requires multi-database support
    (CREATE DATABASE), which is available on Neo4j Enterprise and AuraDB only.
    ```

    Neo4j Community — including the bundled `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:

    1. **Turn per-dataset isolation off** (what the Neo4j blocks above do): `ENABLE_BACKEND_ACCESS_CONTROL="false"`. All datasets then share one graph database.
    2. **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](/core-concepts/multi-user-mode/dataset-database-handlers/existing-dataset-database-handlers/neo4j-community).
    3. **Use Neo4j Enterprise or AuraDB**, where `CREATE DATABASE` is available and the default mode works unchanged.
  </Accordion>

  <Accordion title="Postgres graph store tries to connect to port 123">
    ```text theme={null}
    OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 123)
    ```

    Port `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](#one-postgres-for-everything) 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:

    ```text theme={null}
    Postgres graph credentials are not fully configured; falling back to the relational
    database configuration.
    ```
  </Accordion>

  <Accordion title="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 `EMBEDDING_DIMENSIONS` leaves collections behind that no longer match, which surfaces as empty recalls or dimension-mismatch errors. Clear them once:

    ```python theme={null}
    await cognee.prune.prune_data()
    await cognee.prune.prune_system(metadata=True)
    ```

    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.
  </Accordion>

  <Accordion title="Postgres: the database does not exist">
    Cognee creates its *tables*, but not the database named in `DB_NAME` — for Postgres that must already exist. The bundled Docker service creates `cognee_db` for you; on your own server, create it once:

    ```bash theme={null}
    createdb -h 127.0.0.1 -U cognee cognee_db
    ```

    See [Relational Databases](/setup-configuration/relational-databases#troubleshooting) for the related `DatabaseNotCreatedError` case.
  </Accordion>

  <Accordion title="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`:

    ```dotenv theme={null}
    DB_HOST="host.docker.internal"
    VECTOR_DB_HOST="host.docker.internal"
    GRAPH_DATABASE_URL="bolt://host.docker.internal:7687"
    ```

    When both run under the same Compose project, use the service names instead — `postgres` and `neo4j`.
  </Accordion>

  <Accordion title="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](#verify-your-stack).
  </Accordion>
</AccordionGroup>

## 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](/setup-configuration/community-maintained/overview).

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 with `use_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](#multi-user-access-control-is-on-by-default) 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](/contributing/adding-providers/adding-new-vector-database) and [Graph Database Integration](/contributing/adding-providers/adding-new-graph-database). The relational layer has no registration hook — it is limited to the built-in `sqlite`, `postgres`, and `turso`.

<Columns cols={3}>
  <Card title="Relational Databases" icon="database" href="/setup-configuration/relational-databases">
    Pooling, SSL, managed Postgres, and migration sources
  </Card>

  <Card title="Vector Stores" icon="layers" href="/setup-configuration/vector-stores">
    Per-provider settings, table layout, and subprocess tuning
  </Card>

  <Card title="Graph Stores" icon="network" href="/setup-configuration/graph-stores">
    Every graph backend, including Neptune and remote Kuzu
  </Card>
</Columns>
