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

# Graph Stores

> Configure graph databases for knowledge graph storage and relationship reasoning in Cognee

Graph stores capture entities and relationships in knowledge graphs. They enable Cognee to understand structure and navigate connections between concepts, providing powerful reasoning capabilities.

<Info>
  **New to configuration?**

  See the [Setup Configuration Overview](./overview) for the complete workflow:

  install extras → create `.env` → choose providers → handle pruning.

  For a complete, copy-paste `.env` block that combines this layer with a relational and a vector store, see [Store Configurations](/guides/store-configurations).
</Info>

## Supported Providers

Cognee supports multiple graph store options:

* **Kuzu** — Local file-based graph database (default)
* **Kuzu-remote** — Kuzu with HTTP API access
* **Neo4j** — Production-ready graph database (self-hosted server or Docker)
* **Neo4j Desktop** — Local Neo4j development setup with the Desktop app
* **Neo4j Aura** — Neo4j's fully managed cloud service
* **Postgres** — Stores graph nodes and edges in Postgres tables (demo, not production-ready). Select it with `postgres_demo`; the older value `postgres` is still accepted and resolves to the same adapter
* **Neptune** — Amazon Neptune cloud graph database
* **Neptune Analytics** — Amazon Neptune Analytics hybrid solution
* **Memgraph** — In-memory graph database (community adapter)

<Info>
  **Local vs. cloud storage**: By default Cognee stores its graph in a local Kuzu file. To inspect a graph locally in Neo4j, use Neo4j Desktop. To persist data in the cloud, switch to a remote provider such as Neo4j Aura, Neptune, or a self-hosted Neo4j instance on a remote server.
</Info>

## Configuration

<Accordion title="Environment Variables">
  Set these environment variables in your `.env` file:

  * `GRAPH_DATABASE_PROVIDER` — The graph store provider (kuzu, kuzu-remote, neo4j, postgres\_demo, neptune, neptune\_analytics; `postgres` is accepted as an alias of `postgres_demo`)
  * `GRAPH_DATABASE_URL` — Database URL or connection string
  * `GRAPH_DATABASE_USERNAME` — Database username (optional)
  * `GRAPH_DATABASE_PASSWORD` — Database password (optional)
  * `GRAPH_DATABASE_NAME` — Database name (optional)
  * `SUBPROCESS_OPEN_LOCK_RETRIES` — For the file-based Ladybug/Kuzu store only: how many times a worker retries opening the graph file when another worker is still releasing its on-disk lock (default `10`; set to `0` or a negative value to disable retries and surface the lock error immediately)
  * `SUBPROCESS_OPEN_LOCK_BACKOFF` — For the file-based Ladybug/Kuzu store only: starting delay in seconds for the exponential backoff between those open retries (default `0.1`; per-attempt delay is capped internally)
  * `SUBPROCESS_IDLE_TTL_SECONDS` — For subprocess-backed engines only: how many seconds an idle engine is kept alive before a background reaper closes its worker process (default `600`). While the engine is kept warm it still holds the graph file lock and its memory, and a request arriving inside the window reuses it instead of respawning a worker. Set to `0` to close the engine at every dataset-context exit instead (negative values are clamped to `0`). See [Subprocess engine teardown coordination](/setup-configuration/permissions#subprocess-engine-teardown-coordination) for the full lifecycle
</Accordion>

## Setup Guides

<AccordionGroup>
  <Accordion title="Kuzu (Default)">
    Kuzu is file-based and requires no network setup. It's perfect for local development and single-user scenarios.

    ```dotenv theme={null}
    GRAPH_DATABASE_PROVIDER="kuzu"
    # Optional: override location
    # SYSTEM_ROOT_DIRECTORY=/absolute/path/.cognee_system
    # The graph file will default to <SYSTEM_ROOT_DIRECTORY>/databases/cognee_graph_kuzu
    ```

    **Installation**: Kuzu is included by default with Cognee. No additional installation required.

    **Data Location**: The graph is stored on disk. Path defaults under the Cognee system directory and is created automatically.

    <Warning>
      **Concurrency Limitation**: Kuzu uses file-based locking and is not suitable for concurrent use from different agents or processes. For multi-agent scenarios, use Neo4j instead.

      Cognee runs the embedded Ladybug/Kuzu engine in a dedicated worker process and now retries opening the graph file when it hits transient on-disk lock contention (the `Could not set lock on file` error that could briefly occur while a previously used engine was still shutting down). If you still see this error under heavy churn, tune the open retries and backoff with `SUBPROCESS_OPEN_LOCK_RETRIES` and `SUBPROCESS_OPEN_LOCK_BACKOFF` (see the Environment Variables section above).

      An idle graph worker is also kept alive — and so keeps holding the graph file lock — for up to `SUBPROCESS_IDLE_TTL_SECONDS` (default `600`) after its last use, which is what lets a follow-up request reuse it instead of respawning. Set `SUBPROCESS_IDLE_TTL_SECONDS=0` if you need the lock released at each dataset-context exit, for example when another process or tool has to open the same graph file.
    </Warning>
  </Accordion>

  <Accordion title="Kuzu (Remote API)">
    Use Kuzu with an HTTP API when you need remote access or want to run Kuzu as a service.

    ```dotenv theme={null}
    GRAPH_DATABASE_PROVIDER="kuzu-remote"
    GRAPH_DATABASE_URL="http://localhost:8000"
    GRAPH_DATABASE_USERNAME="<optional>"
    GRAPH_DATABASE_PASSWORD="<optional>"
    ```

    **Installation**: Requires a running Kuzu service exposing an HTTP API.
  </Accordion>

  <Accordion title="Postgres">
    <Warning>
      The Postgres graph store is a **demo feature**. In production, use a graph-native backend such as Kuzu or Neo4j for the graph layer — Postgres remains a good default for the relational, vector, and session layers. A production-ready Postgres graph adapter is available as a licensed product; book a call with our sales team at [cognee.ai](https://www.cognee.ai).
    </Warning>

    Use Postgres as a graph store when you want relational metadata, PGVector, and graph state to live in the same Postgres service.

    ```dotenv theme={null}
    GRAPH_DATABASE_PROVIDER="postgres_demo"
    ```

    `postgres_demo` is the canonical provider name. The older value `postgres` is still accepted and resolves to the same adapter, so existing deployments keep working without a configuration change.

    If `GRAPH_DATABASE_HOST`, `GRAPH_DATABASE_PORT`, `GRAPH_DATABASE_NAME`, `GRAPH_DATABASE_USERNAME`, and `GRAPH_DATABASE_PASSWORD` are omitted, Cognee falls back to the relational `DB_*` settings. This is the usual setup when the same Postgres database backs Cognee metadata, vectors, and graph state:

    ```dotenv theme={null}
    DB_PROVIDER="postgres"
    DB_NAME="cognee_db"
    DB_HOST="127.0.0.1"
    DB_PORT="5432"
    DB_USERNAME="cognee"
    DB_PASSWORD="cognee"
    GRAPH_DATABASE_PROVIDER="postgres_demo"
    ```

    For managed Postgres providers such as Neon, configure SSL and pooler settings through the relational database configuration — the Postgres graph engine reuses `DATABASE_CONNECT_ARGS`. See [Relational Databases](/setup-configuration/relational-databases#managed-postgres-with-ssl-connect-args).

    The Postgres graph backend stores graph data in `graph_node` and `graph_edge` tables. It does not support raw Cypher queries, so both `SearchType.CYPHER` and `SearchType.NATURAL_LANGUAGE` (which generates and executes Cypher) raise `SearchTypeNotSupported` on this backend.

    <Note>
      **Writes are serialized across processes.** Every write path takes a transaction-scoped Postgres advisory lock (`pg_advisory_xact_lock`), so concurrent writers queue instead of running in parallel and updates from separate workers are no longer lost. Reads never take the lock, the lock is released on both commit and rollback, and the database user must be able to acquire advisory locks — standard PostgreSQL installations allow this.
    </Note>
  </Accordion>

  <Accordion title="Neo4j (Self-Hosted)">
    Neo4j is recommended for production environments where you need a powerful, dedicated graph database. Data is stored on the Neo4j server (local or remote), not on the Cognee host machine.

    ```dotenv theme={null}
    GRAPH_DATABASE_PROVIDER="neo4j"
    GRAPH_DATABASE_URL="bolt://localhost:7687"
    GRAPH_DATABASE_NAME="neo4j"
    GRAPH_DATABASE_USERNAME="neo4j"
    GRAPH_DATABASE_PASSWORD="pleaseletmein"
    ```

    **Installation**: Install Neo4j extras:

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

    **Docker Setup**: Start the bundled Neo4j service with APOC + GDS plugins:

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

    **Transient error handling**: Every Cypher query Cognee sends to Neo4j is retried automatically when the server reports a deadlock (`DeadlockDetected`), any `Neo.TransientError`, or a `DatabaseUnavailable` error. Retries use exponential backoff with jitter and allow up to 10 retries after the initial attempt before the original error is re-raised. All three error classes share the same retry budget — previously `DatabaseUnavailable` gave up one attempt earlier than the others. This retry logic is built into Cognee's Neo4j adapter (not the Neo4j driver itself) and is not configurable through an environment variable.
  </Accordion>

  <Accordion title="Neo4j Desktop (Local Development)">
    Use Neo4j Desktop when you want a local Neo4j database with a graphical interface for inspecting Cognee's generated graph, or when you want to test Cognee's [multi-user mode](/core-concepts/multi-user-mode/multi-user-mode-overview) locally. Full multi-user support in Neo4j, including role-based access control and database isolation per user, is otherwise only available in the Enterprise edition; Neo4j Desktop includes these capabilities for local development at no cost. (Alternatively, the [`neo4j_community` dataset database handler](/core-concepts/multi-user-mode/dataset-database-handlers/existing-dataset-database-handlers/neo4j-community) gets per-dataset isolation on the free Community edition by running one Docker container per dataset.) This is still a `neo4j` graph provider from Cognee's perspective; Neo4j Desktop is only how you run and manage the local database.

    <Steps>
      <Step title="Create and start a local database">
        In Neo4j Desktop:

        1. Create a new project
        2. Add a local DBMS/database
        3. Set and save the database password
        4. Start the database

        Keep the Bolt port available at `7687` unless you intentionally changed it.
      </Step>

      <Step title="Install APOC">
        Select the database in Neo4j Desktop, open the plugins area, install **APOC**, then restart the database.

        APOC is required for Cognee's type-specific Neo4j labels. Without it, Cognee can still write graph data, but nodes may only show the generic `__Node__` label in Neo4j Browser.
      </Step>

      <Step title="Configure Cognee">
        Add the Neo4j connection details to your `.env` file:

        ```dotenv theme={null}
        GRAPH_DATABASE_PROVIDER="neo4j"
        GRAPH_DATABASE_URL="bolt://localhost:7687"
        GRAPH_DATABASE_NAME="neo4j"
        GRAPH_DATABASE_USERNAME="neo4j"
        GRAPH_DATABASE_PASSWORD="<your-neo4j-desktop-password>"
        ```

        Install the Neo4j extra in the environment where Cognee runs:

        ```bash theme={null}
        pip install "cognee[neo4j]"
        ```
      </Step>

      <Step title="Verify the connection">
        Open Neo4j Browser from Neo4j Desktop and run:

        ```cypher theme={null}
        RETURN apoc.version() AS apocVersion;
        ```

        If the query returns a version, APOC is available. Then run your Cognee ingestion/search flow and inspect the graph in Neo4j Browser.
      </Step>
    </Steps>

    <Note>
      Neo4j Desktop is best for local development and graph inspection. For team or production deployments, use the Docker/self-hosted setup or Neo4j Aura so the database is managed independently from a developer workstation.
    </Note>
  </Accordion>

  <Accordion title="Neo4j Aura (Cloud)">
    [Neo4j Aura](https://neo4j.com/docs/aura/) is Neo4j's fully managed cloud service. Graph data is stored in Neo4j's cloud infrastructure — nothing is stored locally on your machine.

    There are two ways to use Neo4j Aura with Cognee:

    **Option 1 — Connect to an existing Aura instance**

    Create a free or paid Aura instance at [console.neo4j.io](https://console.neo4j.io), then point Cognee at it using the `neo4j+s://` connection URI provided in your Aura console:

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

    **Option 2 — Auto-provisioned Aura instances per dataset (multi-user mode)**

    Cognee's `Neo4jAuraDevDatasetDatabaseHandler` can automatically create and delete a dedicated Neo4j Aura instance for each Cognee dataset. This requires Neo4j Aura API credentials (OAuth):

    ```dotenv theme={null}
    GRAPH_DATABASE_PROVIDER="neo4j"
    GRAPH_DATASET_DATABASE_HANDLER="neo4j_aura_dev"
    NEO4J_CLIENT_ID=<your_oauth_client_id>
    NEO4J_CLIENT_SECRET=<your_oauth_client_secret>
    NEO4J_TENANT_ID=<your_aura_tenant_id>
    NEO4J_ENCRYPTION_KEY=<key_for_encrypting_stored_credentials>
    ```

    See the [Neo4j Aura Dataset Database Handler](/core-concepts/multi-user-mode/dataset-database-handlers/existing-dataset-database-handlers/neo4j-aura-dev) page for full details on Option 2.

    **Installation**: Install Neo4j extras:

    ```bash theme={null}
    pip install "cognee[neo4j]"
    ```
  </Accordion>

  <Accordion title="Neptune (Graph-only)">
    Use Amazon Neptune for cloud-based graph storage.

    ```dotenv theme={null}
    GRAPH_DATABASE_PROVIDER="neptune"
    GRAPH_DATABASE_URL="neptune-graph://<GRAPH_ID>"
    # AWS credentials via environment or default SDK chain

    # Required — no per-dataset database handler exists for Neptune
    ENABLE_BACKEND_ACCESS_CONTROL="false"
    ```

    **Installation**: Install Neptune extras:

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

    **Note**: AWS credentials should be configured via environment variables or AWS SDK.

    **Access control must be off.** Cognee registers no per-dataset database handler for Neptune, so with `ENABLE_BACKEND_ACCESS_CONTROL` left at its default the handler stays `ladybug` and the first dataset access raises `The selected graph dataset to database handler does not work with the configured graph database provider`. All datasets then share the one graph.
  </Accordion>

  <Accordion title="Neptune Analytics (Hybrid)">
    Use Amazon Neptune Analytics as a hybrid vector + graph backend.

    ```dotenv theme={null}
    GRAPH_DATABASE_PROVIDER="neptune_analytics"
    GRAPH_DATABASE_URL="neptune-graph://<GRAPH_ID>"
    # AWS credentials via environment or default SDK chain

    # Required — no per-dataset database handler exists for Neptune Analytics
    ENABLE_BACKEND_ACCESS_CONTROL="false"
    ```

    **Installation**: Install Neptune extras:

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

    **Note**: This is the same as the vector store configuration. Neptune Analytics serves both purposes.

    **Access control must be off.** Cognee registers no per-dataset database handler for Neptune Analytics, so with `ENABLE_BACKEND_ACCESS_CONTROL` left at its default the first dataset access raises on the handler mismatch. All datasets then share the one graph.
  </Accordion>
</AccordionGroup>

## Advanced Options

<Accordion title="Backend Access Control">
  Enable per-user dataset isolation for multi-tenant scenarios.

  ```dotenv theme={null}
  ENABLE_BACKEND_ACCESS_CONTROL="true"
  ```

  This feature is available for Kuzu and other supported graph stores.
</Accordion>

## Provider Comparison

<Accordion title="Graph Store Comparison">
  | Provider            | Data Location        | Setup                 | Performance | Use Case                                                                                                                                                                            |
  | ------------------- | -------------------- | --------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | Kuzu                | Local disk           | Zero setup            | Good        | Local development                                                                                                                                                                   |
  | Kuzu-remote         | Remote server        | Server required       | Good        | Remote access                                                                                                                                                                       |
  | Neo4j (self-hosted) | Neo4j server         | Server required       | Excellent   | Production                                                                                                                                                                          |
  | Neo4j Desktop       | Local Neo4j database | Desktop app + APOC    | Excellent   | Local development, graph inspection, and local multi-user testing (Enterprise features available at no cost locally)                                                                |
  | Neo4j Aura          | Neo4j cloud          | Aura account required | Excellent   | Managed cloud                                                                                                                                                                       |
  | Postgres            | Postgres tables      | Postgres required     | Good        | **Demo** — co-locates graph state with relational metadata and PGVector. In production, use a graph-native backend or the licensed adapter (via [cognee.ai](https://www.cognee.ai)) |
  | Neptune             | AWS cloud            | AWS required          | Excellent   | Cloud solution                                                                                                                                                                      |
  | Neptune Analytics   | AWS cloud            | AWS required          | Excellent   | Hybrid cloud solution                                                                                                                                                               |
</Accordion>

## Important Considerations

<Accordion title="Data Location">
  * **Local providers** (Kuzu): Graph files are created automatically under `SYSTEM_ROOT_DIRECTORY`
  * **Local Neo4j Desktop**: Graph data is stored in the database managed by Neo4j Desktop, not under Cognee's `SYSTEM_ROOT_DIRECTORY`
  * **Remote providers** (Neo4j, Neptune): Require running services or cloud setup
  * **Path management**: Kuzu graph files are managed automatically; Neo4j Desktop data is managed inside Neo4j Desktop
</Accordion>

<Accordion title="Performance Notes">
  * **Kuzu**: Single-file storage with good local performance
  * **Neo4j**: Excellent for production workloads with proper indexing
  * **Neptune**: Cloud-scale performance with managed infrastructure
  * **Hybrid solutions**: Combine graph and vector capabilities in one system
</Accordion>

## Community-Maintained Providers

Additional graph stores are available through community-maintained adapters:

* **[Memgraph](/setup-configuration/community-maintained/memgraph)** — In-memory graph database (Bolt protocol)

## Notes

<AccordionGroup>
  <Accordion title="Backend Access Control">
    When backend access control is enabled, Cognee can isolate graph data per dataset for supported providers such as Kuzu. This is mainly relevant for multi-user deployments where different users or workloads should not share the same graph state by default.
  </Accordion>

  <Accordion title="Path Management">
    For local Kuzu setups, Cognee creates and manages the graph database automatically under the system directory. In most cases you do not need to manually create graph files or point Cognee at a specific path unless you are customizing `SYSTEM_ROOT_DIRECTORY`.
  </Accordion>

  <Accordion title="Cloud Integration">
    Neptune-based setups rely on AWS credentials, network access, and the appropriate IAM permissions to connect successfully. Before using Neptune or Neptune Analytics, make sure your environment can authenticate through the standard AWS SDK credential chain.
  </Accordion>

  <Accordion title="Neo4j Type Labels">
    **APOC is required for Neo4j type labels.** Cognee uses `apoc.create.addLabels` to apply type-specific labels to every node. Without it, Cognee can still store nodes, but Neo4j will only show the generic `__Node__` label, making entity types harder to inspect directly.

    The bundled Docker Compose Neo4j profile already includes APOC. For self-hosted Neo4j instances, install the [APOC plugin](https://neo4j.com/docs/apoc/current/installation/) before connecting Cognee.
  </Accordion>

  <Accordion title="Troubleshooting: 'No nodes found'">
    The warning `No nodes found in the database` means the graph DB at the current path is empty. Common causes:

    <AccordionGroup>
      <Accordion title="Path mismatch between runs">
        For Kuzu, the graph is stored on disk at:

        ```text theme={null}
        {SYSTEM_ROOT_DIRECTORY}/databases/cognee_graph_kuzu
        ```

        `SYSTEM_ROOT_DIRECTORY` defaults to a `.cognee_system` folder inside the installed Cognee package directory (typically inside your virtual environment). If this path resolves differently across sessions — for example, after reinstalling packages or using a different virtual environment — each session sees an empty graph.

        Pin it to an explicit absolute path in your `.env`:

        ```dotenv theme={null}
        SYSTEM_ROOT_DIRECTORY=/home/user/my-project/.cognee_system
        ```

        Raw ingested files (added via `add()`) are stored separately under `DATA_ROOT_DIRECTORY`, which defaults to `.data_storage` in the same package directory. Set both if you want fully portable storage:

        ```dotenv theme={null}
        SYSTEM_ROOT_DIRECTORY=/home/user/my-project/.cognee_system
        DATA_ROOT_DIRECTORY=/home/user/my-project/.data_storage
        ```
      </Accordion>

      <Accordion title="Data not yet processed in this session">
        The graph persists on disk between runs — you do not need to re-run `add()` + `cognify()` every time. Calling `search()` or [`visualize_graph()`](/guides/graph-visualization) in a new session will find existing data, as long as `SYSTEM_ROOT_DIRECTORY` points to the same location as the original ingestion run.
      </Accordion>

      <Accordion title="Graph was pruned">
        `cognee.prune.prune_system()` deletes all graph and system data. Re-run `add()` and `cognify()` to rebuild it.
      </Accordion>
    </AccordionGroup>
  </Accordion>
</AccordionGroup>

<Columns cols={3}>
  <Card title="Vector Stores" icon="database" href="/setup-configuration/vector-stores">
    Configure vector databases for embedding storage
  </Card>

  <Card title="Relational Databases" icon="database" href="/setup-configuration/relational-databases">
    Set up SQLite or Postgres for metadata storage
  </Card>

  <Card title="Overview" icon="settings" href="/setup-configuration/overview">
    Return to setup configuration overview
  </Card>
</Columns>
