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

# PGVector Dataset Database Handler

> Handler for using PGVector in Cognee multi-user mode.

<Warning>
  Make sure that `ENABLE_BACKEND_ACCESS_CONTROL` in your `.env` file is **NOT** set to `False`.
  Multi-user mode is enabled by default, therefore `ENABLE_BACKEND_ACCESS_CONTROL=True` by default.
</Warning>

The PGVector adapter is one of Cognee's core vector adapters, along with LanceDB. Even though PGVector is
an extension of Postgres, you can use PGVector as a vector store with other relational databases, such as SQLite.

## Installation

Firstly, you will need to install specific dependencies necessary for working with Postgres and PGVector:

```bash theme={null}
pip install "cognee[postgres]"
# or for binary version
pip install "cognee[postgres-binary]"
```

## Setup

You will need a running Postgres database instance, and the existing handler works with both **local** and **cloud** setups.
All you need to do is provide the necessary connection information, like the following example does for a local setup:

```dotenv theme={null}
VECTOR_DB_PROVIDER=pgvector
VECTOR_DB_NAME=<your_db_name>
VECTOR_DB_URL=127.0.0.1
VECTOR_DB_PORT=5432
VECTOR_DB_USERNAME=<your_db_username>
VECTOR_DB_PASSWORD=<your_db_password>
```

For the server setup, you can use the one from the Cognee `docker-compose.yml` file, or your own:

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

## Usage

The PGVector handler is registered in Cognee by default, so all that is left to do is to let
Cognee know which handler you are using. This can be done by setting the following `.env` variable:

```dotenv theme={null}
VECTOR_DATASET_DATABASE_HANDLER="pgvector"
```

### Schema-per-dataset isolation (`pgvector_shared`)

The `pgvector` handler above gives every dataset its own Postgres database (`CREATE DATABASE
"<dataset_id>"`). If you would rather keep everything in a single database, select the
`pgvector_shared` handler instead:

```dotenv theme={null}
VECTOR_DB_PROVIDER=pgvector
VECTOR_DATASET_DATABASE_HANDLER="pgvector_shared"
```

In this mode each dataset's vector collections live in a dedicated **schema** of Cognee's existing
relational database rather than in a separate database:

* **The schema name is derived automatically.** Cognee names it `ds_<dataset_id_hex>` (the dataset
  UUID with hyphens stripped) and stores it in the dataset's `vector_database_connection_info`. You
  do not supply a schema yourself.
* **Connection details come from the relational configuration.** The host, port, database name,
  username, and password are taken from your `DB_HOST` / `DB_PORT` / `DB_NAME` / `DB_USERNAME` /
  `DB_PASSWORD` settings — not from the `VECTOR_DB_*` variables — because the shared database *is*
  Cognee's relational database. Credentials are read from the live relational config at connection
  time and are never persisted in the dataset record.
* **Only `CREATE SCHEMA` privilege is required**, not `CREATE DATABASE`.
* **Provisioning is automatic and idempotent.** On first use Cognee runs `CREATE EXTENSION IF NOT
  EXISTS vector` and `CREATE SCHEMA IF NOT EXISTS`, so re-running `add`/`cognify` is safe and you do
  not need to create the schema or install the pgvector extension by hand.
* **Deleting a dataset drops its schema** with a single `DROP SCHEMA ... CASCADE`, removing every
  table and index the dataset created.

Isolation is enforced by pinning the per-dataset PGVector engine's `search_path` to
`"<dataset schema>, public"`. The dataset schema comes first, so reads and writes never fall through
to `public` (which holds Cognee's shared relational tables), while `public` stays on the path so the
`vector` type remains resolvable. Table listing and deletion for these engines are likewise scoped
to the dataset's own schema.

There is a matching graph handler, `postgres_graph_shared`, which isolates each dataset's
`graph_node`/`graph_edge` tables in the same way. See the
[list of supported handlers](/core-concepts/multi-user-mode/dataset-database-handlers/dataset-database-handlers-how-to-use-them).

<Warning>
  `pgvector_shared` requires `VECTOR_DB_PROVIDER=pgvector`. Selecting it with any other vector
  provider raises a `ValueError` when the dataset database is created.
</Warning>

## Connection pool tuning

In multi-user mode each dataset gets its own PGVector engine, so the total number of open
connections grows with the number of active datasets (number of datasets × pool size). To keep
this fan-out in check, per-dataset PGVector engines fall back to a small connection pool
(`pool_size=2`, `max_overflow=20`) when you have not sized the pool yourself.

With the `pgvector_shared` handler every dataset engine points at the same database, so those pools
all land on one connection target instead of fanning out across a separate database per dataset —
but each dataset still has its own engine and its own pool, so the same sizing guidance applies.

Pool arguments for these engines are resolved from the first source that is set:

1. **`VECTOR_POOL_ARGS`** — explicit PGVector sizing, which always wins.
2. **The relational `POOL_ARGS`** — inherited when `VECTOR_POOL_ARGS` is unset, so an operator who
   sized the pool explicitly outranks the built-in default.
3. **The built-in access-control default** (`pool_size=2`, `max_overflow=20`) — used only when
   neither variable is set.

`VECTOR_POOL_ARGS` takes a JSON object whose keys are passed through to SQLAlchemy's
`create_async_engine`:

```dotenv theme={null}
VECTOR_POOL_ARGS='{"pool_size": 2, "max_overflow": 5, "pool_recycle": 1800}'
```

It applies only to PGVector per-dataset engines; leave it unset if you want these engines to follow
`POOL_ARGS` instead. The value must be a JSON object; invalid JSON raises a configuration error
(`VECTOR_POOL_ARGS must be valid JSON`) at startup. Restart your process or container after
changing it so the new pool settings take effect.

## SSL / connect args for managed Postgres

When a per-dataset PGVector engine connects to managed Postgres that enforces SSL (for example
Neon), it now inherits the relational `DATABASE_CONNECT_ARGS` connection arguments, so asyncpg SSL options
supplied there are honored for these engines too. Leaving `DATABASE_CONNECT_ARGS` unset is a no-op.
See [Relational Databases → Managed Postgres with SSL](/setup-configuration/relational-databases)
for the `DATABASE_CONNECT_ARGS` format.

<CardGroup cols={2}>
  <Card title="Vector Stores" icon="book" href="/setup-configuration/vector-stores">
    Details About Cognee's Vector Stores
  </Card>

  <Card title="Multi-User Overview" icon="users" href="/core-concepts/multi-user-mode/multi-user-mode-overview">
    More Details About Multi-User Mode
  </Card>
</CardGroup>
